├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── MAINTAINERS.md ├── Makefile ├── Makefile.common ├── NOTICE ├── README.md ├── VERSION ├── checkmetrics.sh ├── collector ├── arp_linux.go ├── bcache_linux.go ├── bonding_linux.go ├── bonding_linux_test.go ├── boot_time_bsd.go ├── boot_time_solaris.go ├── btrfs_linux.go ├── btrfs_linux_test.go ├── buddyinfo.go ├── collector.go ├── conntrack_linux.go ├── cpu_common.go ├── cpu_darwin.go ├── cpu_dragonfly.go ├── cpu_dragonfly_test.go ├── cpu_freebsd.go ├── cpu_linux.go ├── cpu_openbsd.go ├── cpu_solaris.go ├── cpufreq_linux.go ├── cpufreq_solaris.go ├── devstat_dragonfly.go ├── devstat_freebsd.c ├── devstat_freebsd.go ├── devstat_freebsd.h ├── diskstats_common.go ├── diskstats_darwin.go ├── diskstats_linux.go ├── diskstats_linux_test.go ├── diskstats_openbsd.go ├── drbd_linux.go ├── edac_linux.go ├── entropy_linux.go ├── exec_bsd.go ├── filefd_linux.go ├── filefd_linux_test.go ├── filesystem_bsd.go ├── filesystem_common.go ├── filesystem_freebsd.go ├── filesystem_linux.go ├── filesystem_linux_test.go ├── fixtures │ ├── e2e-64k-page-output.txt │ ├── e2e-output.txt │ ├── ip_vs_result.txt │ ├── ip_vs_result_lbs_local_address_local_port.txt │ ├── ip_vs_result_lbs_local_port.txt │ ├── ip_vs_result_lbs_none.txt │ ├── proc │ │ ├── 1 │ │ │ └── mounts │ │ ├── 10 │ │ │ ├── mountinfo │ │ │ ├── mountstats │ │ │ └── stat │ │ ├── 11 │ │ │ └── .missing_stat │ │ ├── buddyinfo │ │ ├── cpuinfo │ │ ├── diskstats │ │ ├── drbd │ │ ├── interrupts │ │ ├── loadavg │ │ ├── mdstat │ │ ├── meminfo │ │ ├── net │ │ │ ├── arp │ │ │ ├── dev │ │ │ ├── ip_vs │ │ │ ├── ip_vs_stats │ │ │ ├── netstat │ │ │ ├── rpc │ │ │ │ ├── nfs │ │ │ │ └── nfsd │ │ │ ├── snmp │ │ │ ├── snmp6 │ │ │ ├── sockstat │ │ │ ├── sockstat6 │ │ │ ├── softnet_stat │ │ │ ├── tcpstat │ │ │ └── udp │ │ ├── pressure │ │ │ ├── cpu │ │ │ ├── io │ │ │ └── memory │ │ ├── schedstat │ │ ├── self │ │ │ ├── mountinfo │ │ │ ├── mountstats │ │ │ └── stat │ │ ├── spl │ │ │ └── kstat │ │ │ │ └── zfs │ │ │ │ ├── abdstats │ │ │ │ ├── arcstats │ │ │ │ ├── dbuf_stats │ │ │ │ ├── dmu_tx │ │ │ │ ├── dnodestats │ │ │ │ ├── fm │ │ │ │ ├── pool1 │ │ │ │ ├── io │ │ │ │ ├── objset-1 │ │ │ │ └── objset-2 │ │ │ │ ├── poolz1 │ │ │ │ ├── io │ │ │ │ ├── objset-1 │ │ │ │ └── objset-2 │ │ │ │ ├── vdev_cache_stats │ │ │ │ ├── vdev_mirror_stats │ │ │ │ ├── xuio_stats │ │ │ │ ├── zfetchstats │ │ │ │ └── zil │ │ ├── stat │ │ ├── sys │ │ │ ├── fs │ │ │ │ └── file-nr │ │ │ ├── kernel │ │ │ │ ├── pid_max │ │ │ │ ├── random │ │ │ │ │ └── entropy_avail │ │ │ │ └── threads-max │ │ │ ├── net │ │ │ │ └── netfilter │ │ │ │ │ ├── nf_conntrack_count │ │ │ │ │ └── nf_conntrack_max │ │ │ ├── pid_max │ │ │ └── threads-max │ │ └── vmstat │ ├── qdisc │ │ └── results.json │ ├── sys.ttar │ ├── textfile │ │ ├── client_side_timestamp │ │ │ └── metrics.prom │ │ ├── different_metric_types │ │ │ └── metrics.prom │ │ ├── histogram │ │ │ └── metrics.prom │ │ ├── histogram_extra_dimension │ │ │ └── metrics.prom │ │ ├── inconsistent_metrics │ │ │ └── metrics.prom │ │ ├── no_metric_files │ │ │ └── non_matching_file.txt │ │ ├── summary │ │ │ └── metrics.prom │ │ ├── summary_extra_dimension │ │ │ └── metrics.prom │ │ └── two_metric_files │ │ │ ├── metrics1.prom │ │ │ ├── metrics2.prom │ │ │ └── non_matching_file.txt │ └── wifi │ │ ├── interfaces.json │ │ └── wlan0 │ │ ├── bss.json │ │ └── stationinfo.json ├── fixtures_bindmount │ └── proc │ │ └── mounts ├── fixtures_hidepid │ └── proc │ │ └── mounts ├── helper.go ├── helper_test.go ├── hwmon_linux.go ├── infiniband_linux.go ├── interrupts_common.go ├── interrupts_linux.go ├── interrupts_linux_test.go ├── interrupts_openbsd.go ├── ipvs_linux.go ├── ipvs_linux_test.go ├── ksmd_linux.go ├── kvm_bsd.c ├── kvm_bsd.go ├── kvm_bsd.h ├── loadavg.go ├── loadavg_bsd.go ├── loadavg_linux.go ├── loadavg_linux_test.go ├── loadavg_solaris.go ├── logind_linux.go ├── logind_linux_test.go ├── mdadm_linux.go ├── meminfo.go ├── meminfo_darwin.go ├── meminfo_linux.go ├── meminfo_linux_test.go ├── meminfo_numa_linux.go ├── meminfo_numa_linux_test.go ├── meminfo_openbsd.go ├── memory_bsd.go ├── mountstats_linux.go ├── netclass_linux.go ├── netdev_bsd.go ├── netdev_bsd_test.go ├── netdev_common.go ├── netdev_darwin.go ├── netdev_linux.go ├── netdev_linux_test.go ├── netdev_openbsd.go ├── netstat_linux.go ├── netstat_linux_test.go ├── nfs_linux.go ├── nfsd_linux.go ├── ntp.go ├── paths.go ├── paths_test.go ├── perf_linux.go ├── perf_linux_test.go ├── powersupplyclass.go ├── pressure_linux.go ├── processes_linux.go ├── processes_linux_test.go ├── qdisc_linux.go ├── rapl_linux.go ├── runit.go ├── schedstat_linux.go ├── sockstat_linux.go ├── softnet_linux.go ├── stat_linux.go ├── supervisord.go ├── sysctl_bsd.go ├── systemd_linux.go ├── systemd_linux_test.go ├── tcpstat_linux.go ├── tcpstat_linux_test.go ├── textfile.go ├── textfile_test.go ├── thermal_zone_linux.go ├── time.go ├── timex.go ├── udp_queues_linux.go ├── uname.go ├── uname_bsd.go ├── uname_linux.go ├── vmstat_linux.go ├── wifi_linux.go ├── xfs_linux.go ├── zfs.go ├── zfs_freebsd.go ├── zfs_linux.go ├── zfs_linux_test.go └── zfs_solaris.go ├── docs ├── TIME.md ├── V0_16_UPGRADE_GUIDE.md ├── example-16-compatibility-rules-new-to-old.yml ├── example-16-compatibility-rules.yml ├── example-17-compatibility-rules-new-to-old.yml ├── example-17-compatibility-rules.yml └── node-mixin │ ├── .gitignore │ ├── Makefile │ ├── README.md │ ├── alerts.jsonnet │ ├── alerts │ └── alerts.libsonnet │ ├── config.libsonnet │ ├── dashboards.jsonnet │ ├── dashboards │ ├── dashboards.libsonnet │ ├── node.libsonnet │ └── use.libsonnet │ ├── jsonnetfile.json │ ├── mixin.libsonnet │ ├── rules.jsonnet │ └── rules │ └── rules.libsonnet ├── end-to-end-test.sh ├── example-rules.yml ├── examples ├── init.d │ └── node_exporter ├── launchctl │ ├── README.md │ └── io.prometheus.node_exporter.plist ├── openbsd-rc.d │ └── node_exporter ├── openwrt-init.d │ └── node_exporter └── systemd │ ├── README.md │ ├── node_exporter.service │ └── sysconfig.node_exporter ├── go.mod ├── go.sum ├── https ├── README.md ├── testdata │ ├── server.crt │ ├── server.key │ ├── tls-ca-chain.pem │ ├── tls_config_auth_clientCAs_invalid.bad.yml │ ├── tls_config_auth_clientCAs_missing.bad.yml │ ├── tls_config_auth_user_list_invalid.bad.yml │ ├── tls_config_empty.yml │ ├── tls_config_junk.yml │ ├── tls_config_junk_key.yml │ ├── tls_config_noAuth.bad.yml │ ├── tls_config_noAuth.good.blocking.yml │ ├── tls_config_noAuth.good.yml │ ├── tls_config_noAuth_allCiphers.good.yml │ ├── tls_config_noAuth_allCurves.good.yml │ ├── tls_config_noAuth_certPath_empty.bad.yml │ ├── tls_config_noAuth_certPath_invalid.bad.yml │ ├── tls_config_noAuth_certPath_keyPath_empty.bad.yml │ ├── tls_config_noAuth_certPath_keyPath_invalid.bad.yml │ ├── tls_config_noAuth_inventedCiphers.bad.yml │ ├── tls_config_noAuth_inventedCurves.bad.yml │ ├── tls_config_noAuth_keyPath_empty.bad.yml │ ├── tls_config_noAuth_keyPath_invalid.bad.yml │ ├── tls_config_noAuth_noHTTP2.good.yml │ ├── tls_config_noAuth_noHTTP2Cipher.bad.yml │ ├── tls_config_noAuth_someCiphers.good.yml │ ├── tls_config_noAuth_someCiphers_noOrder.good.yml │ ├── tls_config_noAuth_someCurves.good.yml │ ├── tls_config_noAuth_wrongTLSVersion.bad.yml │ ├── tls_config_users.good.yml │ └── tls_config_users_noTLS.good.yml ├── tls_config.go ├── tls_config_test.go ├── users.go └── web-config.yml ├── node_exporter.go ├── node_exporter_test.go ├── scripts └── errcheck_excludes.txt ├── staticcheck.conf ├── test_image.sh ├── text_collector_examples └── README.md ├── tls_config_noAuth.bad.yml └── ttar /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | vendor/ 16 | 17 | .idea 18 | build 19 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Prometheus Community Code of Conduct 2 | 3 | Prometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Prometheus uses GitHub to manage reviews of pull requests. 4 | 5 | * If you have a trivial fix or improvement, go ahead and create a pull request, 6 | addressing (with `@...`) the maintainer of this repository (see 7 | [MAINTAINERS.md](MAINTAINERS.md)) in the description of the pull request. 8 | 9 | * If you plan to do something more involved, first discuss your ideas 10 | on our [mailing list](https://groups.google.com/forum/?fromgroups#!forum/prometheus-developers). 11 | This will avoid unnecessary work and surely give you and us a good deal 12 | of inspiration. 13 | 14 | * Relevant coding style guidelines are the [Go Code Review 15 | Comments](https://code.google.com/p/go-wiki/wiki/CodeReviewComments) 16 | and the _Formatting and style_ section of Peter Bourgon's [Go: Best 17 | Practices for Production 18 | Environments](http://peter.bourgon.org/go-in-production/#formatting-and-style). 19 | 20 | * Sign your work to certify that your changes were created by yourself or you 21 | have the right to submit it under our license. Read 22 | https://developercertificate.org/ for all details and append your sign-off to 23 | every commit message like this: 24 | 25 | Signed-off-by: Random J Developer 26 | 27 | 28 | ## Collector Implementation Guidelines 29 | 30 | The Node Exporter is not a general monitoring agent. Its sole purpose is to 31 | expose machine metrics, as oppose to service metrics, with the only exception 32 | being the textfile collector. 33 | 34 | The metrics should not get transformed in a way that is hardware specific and 35 | would require maintaining any form of vendor based mappings or conditions. If 36 | for example a proc file contains the magic number 42 as some identifier, the 37 | Node Exporter should expose it as it is and not keep a mapping in code to make 38 | this human readable. Instead, the textfile collector can be used to add a static 39 | metric which can be joined with the metrics exposed by the exporter to get human 40 | readable identifier. 41 | 42 | A Collector may only read `/proc` or `/sys` files, use system calls or local 43 | sockets to retrieve metrics. It may not require root privileges. Running 44 | external commands is not allowed for performance and reliability reasons. Use a 45 | dedicated exporter instead or gather the metrics via the textfile collector. 46 | 47 | The Node Exporter tries to support the most common machine metrics. For more 48 | exotic metrics, use the textfile collector or a dedicated Exporter. 49 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ARG ARCH="amd64" 2 | ARG OS="linux" 3 | FROM quay.io/prometheus/busybox-${OS}-${ARCH}:glibc 4 | LABEL maintainer="The Prometheus Authors " 5 | 6 | ARG ARCH="amd64" 7 | ARG OS="linux" 8 | COPY .build/${OS}-${ARCH}/node_exporter /bin/node_exporter 9 | 10 | EXPOSE 9100 11 | USER nobody 12 | ENTRYPOINT [ "/bin/node_exporter" ] 13 | -------------------------------------------------------------------------------- /MAINTAINERS.md: -------------------------------------------------------------------------------- 1 | * Ben Kochie @SuperQ 2 | * Johannes 'fish' Ziemke @discordianfish 3 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Configurable modular Prometheus exporter for various node metrics. 2 | Copyright 2013-2015 The Prometheus Authors 3 | 4 | This product includes software developed at 5 | SoundCloud Ltd. (http://soundcloud.com/). 6 | 7 | The following components are included in this product: 8 | 9 | wifi 10 | https://github.com/mdlayher/wifi 11 | Copyright 2016-2017 Matt Layher 12 | Licensed under the MIT License 13 | 14 | netlink 15 | https://github.com/mdlayher/netlink 16 | Copyright 2016-2017 Matt Layher 17 | Licensed under the MIT License 18 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 1.0.1 2 | -------------------------------------------------------------------------------- /checkmetrics.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [[ ( -z "$1" ) || ( -z "$2" ) ]]; then 4 | echo "usage: ./checkmetrics.sh /usr/bin/promtool e2e-output.txt" 5 | exit 1 6 | fi 7 | 8 | # Ignore known issues in auto-generated and network specific collectors. 9 | lint=$($1 check metrics < "$2" 2>&1 | grep -v -E "^node_(entropy|memory|netstat|wifi_station)_") 10 | 11 | if [[ -n $lint ]]; then 12 | echo -e "Some Prometheus metrics do not follow best practices:\n" 13 | echo "$lint" 14 | 15 | exit 1 16 | fi 17 | -------------------------------------------------------------------------------- /collector/bonding_linux_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package collector 15 | 16 | import ( 17 | "testing" 18 | ) 19 | 20 | func TestBonding(t *testing.T) { 21 | bondingStats, err := readBondingStats("fixtures/sys/class/net") 22 | if err != nil { 23 | t.Fatal(err) 24 | } 25 | if bondingStats["bond0"][0] != 0 || bondingStats["bond0"][1] != 0 { 26 | t.Fatal("bond0 in unexpected state") 27 | } 28 | 29 | if bondingStats["int"][0] != 2 || bondingStats["int"][1] != 1 { 30 | t.Fatal("int in unexpected state") 31 | } 32 | 33 | if bondingStats["dmz"][0] != 2 || bondingStats["dmz"][1] != 2 { 34 | t.Fatal("dmz in unexpected state") 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /collector/boot_time_bsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build freebsd dragonfly openbsd netbsd darwin 15 | // +build !noboottime 16 | 17 | package collector 18 | 19 | import ( 20 | "github.com/go-kit/kit/log" 21 | "github.com/prometheus/client_golang/prometheus" 22 | ) 23 | 24 | type bootTimeCollector struct { 25 | boottime bsdSysctl 26 | logger log.Logger 27 | } 28 | 29 | func init() { 30 | registerCollector("boottime", defaultEnabled, newBootTimeCollector) 31 | } 32 | 33 | // newBootTimeCollector returns a new Collector exposing system boot time on BSD systems. 34 | func newBootTimeCollector(logger log.Logger) (Collector, error) { 35 | return &bootTimeCollector{ 36 | boottime: bsdSysctl{ 37 | name: "boot_time_seconds", 38 | description: "Unix time of last boot, including microseconds.", 39 | mib: "kern.boottime", 40 | dataType: bsdSysctlTypeStructTimeval, 41 | }, 42 | logger: logger, 43 | }, nil 44 | } 45 | 46 | // Update pushes boot time onto ch 47 | func (c *bootTimeCollector) Update(ch chan<- prometheus.Metric) error { 48 | v, err := c.boottime.Value() 49 | if err != nil { 50 | return err 51 | } 52 | 53 | ch <- prometheus.MustNewConstMetric( 54 | prometheus.NewDesc( 55 | prometheus.BuildFQName(namespace, "", c.boottime.name), 56 | c.boottime.description, 57 | nil, nil, 58 | ), prometheus.GaugeValue, v) 59 | 60 | return nil 61 | } 62 | -------------------------------------------------------------------------------- /collector/boot_time_solaris.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build solaris 15 | // +build !noboottime 16 | 17 | package collector 18 | 19 | import ( 20 | "github.com/go-kit/kit/log" 21 | "github.com/prometheus/client_golang/prometheus" 22 | "github.com/siebenmann/go-kstat" 23 | ) 24 | 25 | type bootTimeCollector struct { 26 | boottime typedDesc 27 | logger log.Logger 28 | } 29 | 30 | func init() { 31 | registerCollector("boottime", defaultEnabled, newBootTimeCollector) 32 | } 33 | 34 | func newBootTimeCollector(logger log.Logger) (Collector, error) { 35 | return &bootTimeCollector{ 36 | boottime: typedDesc{ 37 | prometheus.NewDesc( 38 | prometheus.BuildFQName(namespace, "", "boot_time_seconds"), 39 | "Unix time of last boot, including microseconds.", 40 | nil, nil, 41 | ), prometheus.GaugeValue}, 42 | logger: logger, 43 | }, nil 44 | } 45 | 46 | // newBootTimeCollector returns a new Collector exposing system boot time on Solaris systems. 47 | // Update pushes boot time onto ch 48 | func (c *bootTimeCollector) Update(ch chan<- prometheus.Metric) error { 49 | tok, err := kstat.Open() 50 | if err != nil { 51 | return err 52 | } 53 | 54 | defer tok.Close() 55 | 56 | ks, err := tok.Lookup("unix", 0, "system_misc") 57 | if err != nil { 58 | return err 59 | } 60 | 61 | v, err := ks.GetNamed("boot_time") 62 | if err != nil { 63 | return err 64 | } 65 | 66 | ch <- c.boottime.mustNewConstMetric(float64(v.UintVal)) 67 | 68 | return nil 69 | } 70 | -------------------------------------------------------------------------------- /collector/buddyinfo.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !nobuddyinfo 15 | // +build !netbsd 16 | 17 | package collector 18 | 19 | import ( 20 | "fmt" 21 | "strconv" 22 | 23 | "github.com/go-kit/kit/log" 24 | "github.com/go-kit/kit/log/level" 25 | "github.com/prometheus/client_golang/prometheus" 26 | "github.com/prometheus/procfs" 27 | ) 28 | 29 | const ( 30 | buddyInfoSubsystem = "buddyinfo" 31 | ) 32 | 33 | type buddyinfoCollector struct { 34 | fs procfs.FS 35 | desc *prometheus.Desc 36 | logger log.Logger 37 | } 38 | 39 | func init() { 40 | registerCollector("buddyinfo", defaultDisabled, NewBuddyinfoCollector) 41 | } 42 | 43 | // NewBuddyinfoCollector returns a new Collector exposing buddyinfo stats. 44 | func NewBuddyinfoCollector(logger log.Logger) (Collector, error) { 45 | desc := prometheus.NewDesc( 46 | prometheus.BuildFQName(namespace, buddyInfoSubsystem, "blocks"), 47 | "Count of free blocks according to size.", 48 | []string{"node", "zone", "size"}, nil, 49 | ) 50 | fs, err := procfs.NewFS(*procPath) 51 | if err != nil { 52 | return nil, fmt.Errorf("failed to open procfs: %w", err) 53 | } 54 | return &buddyinfoCollector{fs, desc, logger}, nil 55 | } 56 | 57 | // Update calls (*buddyinfoCollector).getBuddyInfo to get the platform specific 58 | // buddyinfo metrics. 59 | func (c *buddyinfoCollector) Update(ch chan<- prometheus.Metric) error { 60 | buddyInfo, err := c.fs.BuddyInfo() 61 | if err != nil { 62 | return fmt.Errorf("couldn't get buddyinfo: %w", err) 63 | } 64 | 65 | level.Debug(c.logger).Log("msg", "Set node_buddy", "buddyInfo", buddyInfo) 66 | for _, entry := range buddyInfo { 67 | for size, value := range entry.Sizes { 68 | ch <- prometheus.MustNewConstMetric( 69 | c.desc, 70 | prometheus.GaugeValue, value, 71 | entry.Node, entry.Zone, strconv.Itoa(size), 72 | ) 73 | } 74 | } 75 | return nil 76 | } 77 | -------------------------------------------------------------------------------- /collector/conntrack_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !noconntrack 15 | 16 | package collector 17 | 18 | import ( 19 | "github.com/go-kit/kit/log" 20 | "github.com/prometheus/client_golang/prometheus" 21 | ) 22 | 23 | type conntrackCollector struct { 24 | current *prometheus.Desc 25 | limit *prometheus.Desc 26 | logger log.Logger 27 | } 28 | 29 | func init() { 30 | registerCollector("conntrack", defaultEnabled, NewConntrackCollector) 31 | } 32 | 33 | // NewConntrackCollector returns a new Collector exposing conntrack stats. 34 | func NewConntrackCollector(logger log.Logger) (Collector, error) { 35 | return &conntrackCollector{ 36 | current: prometheus.NewDesc( 37 | prometheus.BuildFQName(namespace, "", "nf_conntrack_entries"), 38 | "Number of currently allocated flow entries for connection tracking.", 39 | nil, nil, 40 | ), 41 | limit: prometheus.NewDesc( 42 | prometheus.BuildFQName(namespace, "", "nf_conntrack_entries_limit"), 43 | "Maximum size of connection tracking table.", 44 | nil, nil, 45 | ), 46 | logger: logger, 47 | }, nil 48 | } 49 | 50 | func (c *conntrackCollector) Update(ch chan<- prometheus.Metric) error { 51 | value, err := readUintFromFile(procFilePath("sys/net/netfilter/nf_conntrack_count")) 52 | if err != nil { 53 | // Conntrack probably not loaded into the kernel. 54 | return nil 55 | } 56 | ch <- prometheus.MustNewConstMetric( 57 | c.current, prometheus.GaugeValue, float64(value)) 58 | 59 | value, err = readUintFromFile(procFilePath("sys/net/netfilter/nf_conntrack_max")) 60 | if err != nil { 61 | return nil 62 | } 63 | ch <- prometheus.MustNewConstMetric( 64 | c.limit, prometheus.GaugeValue, float64(value)) 65 | 66 | return nil 67 | } 68 | -------------------------------------------------------------------------------- /collector/cpu_common.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !nocpu 15 | 16 | package collector 17 | 18 | import ( 19 | "github.com/prometheus/client_golang/prometheus" 20 | ) 21 | 22 | const ( 23 | cpuCollectorSubsystem = "cpu" 24 | ) 25 | 26 | var ( 27 | nodeCPUSecondsDesc = prometheus.NewDesc( 28 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "seconds_total"), 29 | "Seconds the cpus spent in each mode.", 30 | []string{"cpu", "mode"}, nil, 31 | ) 32 | ) 33 | -------------------------------------------------------------------------------- /collector/cpu_dragonfly_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !nocpu 15 | 16 | package collector 17 | 18 | import ( 19 | "runtime" 20 | "testing" 21 | ) 22 | 23 | func TestCPU(t *testing.T) { 24 | var ( 25 | fieldsCount = 5 26 | times, err = getDragonFlyCPUTimes() 27 | ) 28 | 29 | if err != nil { 30 | t.Fatalf("expected no error, got %v", err) 31 | } 32 | 33 | if len(times) == 0 { 34 | t.Fatalf("no cputimes found") 35 | } 36 | 37 | want := runtime.NumCPU() * fieldsCount 38 | if len(times) != want { 39 | t.Fatalf("should have %d cpuTimes: got %d", want, len(times)) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /collector/cpu_openbsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !nocpu 15 | 16 | package collector 17 | 18 | import ( 19 | "strconv" 20 | "unsafe" 21 | 22 | "github.com/go-kit/kit/log" 23 | "github.com/prometheus/client_golang/prometheus" 24 | "golang.org/x/sys/unix" 25 | ) 26 | 27 | /* 28 | #include 29 | #include 30 | */ 31 | import "C" 32 | 33 | type cpuCollector struct { 34 | cpu typedDesc 35 | logger log.Logger 36 | } 37 | 38 | func init() { 39 | registerCollector("cpu", defaultEnabled, NewCPUCollector) 40 | } 41 | 42 | func NewCPUCollector(logger log.Logger) (Collector, error) { 43 | return &cpuCollector{ 44 | cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue}, 45 | logger: logger, 46 | }, nil 47 | } 48 | 49 | func (c *cpuCollector) Update(ch chan<- prometheus.Metric) (err error) { 50 | clockb, err := unix.SysctlRaw("kern.clockrate") 51 | if err != nil { 52 | return err 53 | } 54 | clock := *(*C.struct_clockinfo)(unsafe.Pointer(&clockb[0])) 55 | hz := float64(clock.stathz) 56 | 57 | ncpus, err := unix.SysctlUint32("hw.ncpu") 58 | if err != nil { 59 | return err 60 | } 61 | 62 | var cpTime [][C.CPUSTATES]C.int64_t 63 | for i := 0; i < int(ncpus); i++ { 64 | cpb, err := unix.SysctlRaw("kern.cp_time2", i) 65 | if err != nil && err != unix.ENODEV { 66 | return err 67 | } 68 | if err != unix.ENODEV { 69 | cpTime = append(cpTime, *(*[C.CPUSTATES]C.int64_t)(unsafe.Pointer(&cpb[0]))) 70 | } 71 | } 72 | 73 | for cpu, time := range cpTime { 74 | lcpu := strconv.Itoa(cpu) 75 | ch <- c.cpu.mustNewConstMetric(float64(time[C.CP_USER])/hz, lcpu, "user") 76 | ch <- c.cpu.mustNewConstMetric(float64(time[C.CP_NICE])/hz, lcpu, "nice") 77 | ch <- c.cpu.mustNewConstMetric(float64(time[C.CP_SYS])/hz, lcpu, "system") 78 | ch <- c.cpu.mustNewConstMetric(float64(time[C.CP_INTR])/hz, lcpu, "interrupt") 79 | ch <- c.cpu.mustNewConstMetric(float64(time[C.CP_IDLE])/hz, lcpu, "idle") 80 | } 81 | return err 82 | } 83 | -------------------------------------------------------------------------------- /collector/cpu_solaris.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build solaris 15 | // +build !nocpu 16 | 17 | package collector 18 | 19 | import ( 20 | "strconv" 21 | 22 | "github.com/go-kit/kit/log" 23 | "github.com/prometheus/client_golang/prometheus" 24 | kstat "github.com/siebenmann/go-kstat" 25 | ) 26 | 27 | // #include 28 | import "C" 29 | 30 | type cpuCollector struct { 31 | cpu typedDesc 32 | logger log.Logger 33 | } 34 | 35 | func init() { 36 | registerCollector("cpu", defaultEnabled, NewCpuCollector) 37 | } 38 | 39 | func NewCpuCollector(logger log.Logger) (Collector, error) { 40 | return &cpuCollector{ 41 | cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue}, 42 | logger: logger, 43 | }, nil 44 | } 45 | 46 | func (c *cpuCollector) Update(ch chan<- prometheus.Metric) error { 47 | ncpus := C.sysconf(C._SC_NPROCESSORS_ONLN) 48 | 49 | tok, err := kstat.Open() 50 | if err != nil { 51 | return err 52 | } 53 | 54 | defer tok.Close() 55 | 56 | for cpu := 0; cpu < int(ncpus); cpu++ { 57 | ksCPU, err := tok.Lookup("cpu", cpu, "sys") 58 | if err != nil { 59 | return err 60 | } 61 | 62 | for k, v := range map[string]string{ 63 | "idle": "cpu_ticks_idle", 64 | "kernel": "cpu_ticks_kernel", 65 | "user": "cpu_ticks_user", 66 | "wait": "cpu_ticks_wait", 67 | } { 68 | kstatValue, err := ksCPU.GetNamed(v) 69 | if err != nil { 70 | return err 71 | } 72 | 73 | ch <- c.cpu.mustNewConstMetric(float64(kstatValue.UintVal), strconv.Itoa(cpu), k) 74 | } 75 | } 76 | return nil 77 | } 78 | -------------------------------------------------------------------------------- /collector/cpufreq_solaris.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build solaris 15 | // +build !nocpu 16 | 17 | package collector 18 | 19 | import ( 20 | "fmt" 21 | "strconv" 22 | 23 | "github.com/go-kit/kit/log" 24 | "github.com/prometheus/client_golang/prometheus" 25 | kstat "github.com/siebenmann/go-kstat" 26 | ) 27 | 28 | // #include 29 | import "C" 30 | 31 | type cpuFreqCollector struct { 32 | cpuFreq *prometheus.Desc 33 | cpuFreqMax *prometheus.Desc 34 | logger log.Logger 35 | } 36 | 37 | func init() { 38 | registerCollector("cpufreq", defaultEnabled, NewCpuFreqCollector) 39 | } 40 | 41 | func NewCpuFreqCollector(logger log.Logger) (Collector, error) { 42 | return &cpuFreqCollector{ 43 | cpuFreq: prometheus.NewDesc( 44 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "frequency_hertz"), 45 | "Current cpu thread frequency in hertz.", 46 | []string{"cpu"}, nil, 47 | ), 48 | cpuFreqMax: prometheus.NewDesc( 49 | prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "frequency_max_hertz"), 50 | "Maximum cpu thread frequency in hertz.", 51 | []string{"cpu"}, nil, 52 | ), 53 | logger: logger, 54 | }, nil 55 | } 56 | 57 | func (c *cpuFreqCollector) Update(ch chan<- prometheus.Metric) error { 58 | ncpus := C.sysconf(C._SC_NPROCESSORS_ONLN) 59 | 60 | tok, err := kstat.Open() 61 | if err != nil { 62 | return err 63 | } 64 | 65 | defer tok.Close() 66 | 67 | for cpu := 0; cpu < int(ncpus); cpu++ { 68 | ksCPUInfo, err := tok.Lookup("cpu_info", cpu, fmt.Sprintf("cpu_info%d", cpu)) 69 | if err != nil { 70 | return err 71 | } 72 | cpuFreqV, err := ksCPUInfo.GetNamed("current_clock_Hz") 73 | if err != nil { 74 | return err 75 | } 76 | 77 | cpuFreqMaxV, err := ksCPUInfo.GetNamed("clock_MHz") 78 | if err != nil { 79 | return err 80 | } 81 | 82 | lcpu := strconv.Itoa(cpu) 83 | ch <- prometheus.MustNewConstMetric( 84 | c.cpuFreq, 85 | prometheus.GaugeValue, 86 | float64(cpuFreqV.UintVal), 87 | lcpu, 88 | ) 89 | // Multiply by 1e+6 to convert MHz to Hz. 90 | ch <- prometheus.MustNewConstMetric( 91 | c.cpuFreqMax, 92 | prometheus.GaugeValue, 93 | float64(cpuFreqMaxV.IntVal)*1e+6, 94 | lcpu, 95 | ) 96 | } 97 | return nil 98 | } 99 | -------------------------------------------------------------------------------- /collector/devstat_freebsd.c: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !nodevstat 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | 26 | int _get_stats(struct devinfo *info, Stats **stats) { 27 | struct statinfo current; 28 | current.dinfo = info; 29 | 30 | if (devstat_getdevs(NULL, ¤t) == -1) { 31 | return -1; 32 | } 33 | 34 | Stats *p = (Stats*)calloc(current.dinfo->numdevs, sizeof(Stats)); 35 | for (int i = 0; i < current.dinfo->numdevs; i++) { 36 | uint64_t bytes_read, bytes_write, bytes_free; 37 | uint64_t transfers_other, transfers_read, transfers_write, transfers_free; 38 | long double duration_other, duration_read, duration_write, duration_free; 39 | long double busy_time; 40 | uint64_t blocks; 41 | 42 | strcpy(p[i].device, current.dinfo->devices[i].device_name); 43 | p[i].unit = current.dinfo->devices[i].unit_number; 44 | devstat_compute_statistics(¤t.dinfo->devices[i], 45 | NULL, 46 | 1.0, 47 | DSM_TOTAL_BYTES_READ, &bytes_read, 48 | DSM_TOTAL_BYTES_WRITE, &bytes_write, 49 | DSM_TOTAL_BYTES_FREE, &bytes_free, 50 | DSM_TOTAL_TRANSFERS_OTHER, &transfers_other, 51 | DSM_TOTAL_TRANSFERS_READ, &transfers_read, 52 | DSM_TOTAL_TRANSFERS_WRITE, &transfers_write, 53 | DSM_TOTAL_TRANSFERS_FREE, &transfers_free, 54 | DSM_TOTAL_DURATION_OTHER, &duration_other, 55 | DSM_TOTAL_DURATION_READ, &duration_read, 56 | DSM_TOTAL_DURATION_WRITE, &duration_write, 57 | DSM_TOTAL_DURATION_FREE, &duration_free, 58 | DSM_TOTAL_BUSY_TIME, &busy_time, 59 | DSM_TOTAL_BLOCKS, &blocks, 60 | DSM_NONE); 61 | 62 | p[i].bytes.read = bytes_read; 63 | p[i].bytes.write = bytes_write; 64 | p[i].bytes.free = bytes_free; 65 | p[i].transfers.other = transfers_other; 66 | p[i].transfers.read = transfers_read; 67 | p[i].transfers.write = transfers_write; 68 | p[i].transfers.free = transfers_free; 69 | p[i].duration.other = duration_other; 70 | p[i].duration.read = duration_read; 71 | p[i].duration.write = duration_write; 72 | p[i].duration.free = duration_free; 73 | p[i].busyTime = busy_time; 74 | p[i].blocks = blocks; 75 | } 76 | 77 | *stats = p; 78 | return current.dinfo->numdevs; 79 | } 80 | -------------------------------------------------------------------------------- /collector/devstat_freebsd.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | typedef struct { 23 | uint64_t read; 24 | uint64_t write; 25 | uint64_t free; 26 | } Bytes; 27 | 28 | typedef struct { 29 | uint64_t other; 30 | uint64_t read; 31 | uint64_t write; 32 | uint64_t free; 33 | } Transfers; 34 | 35 | typedef struct { 36 | double other; 37 | double read; 38 | double write; 39 | double free; 40 | } Duration; 41 | 42 | typedef struct { 43 | char device[DEVSTAT_NAME_LEN]; 44 | int unit; 45 | Bytes bytes; 46 | Transfers transfers; 47 | Duration duration; 48 | long busyTime; 49 | uint64_t blocks; 50 | } Stats; 51 | 52 | 53 | int _get_ndevs(); 54 | int _get_stats(struct devinfo *info, Stats **stats); 55 | -------------------------------------------------------------------------------- /collector/diskstats_common.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !nodiskstats 15 | // +build openbsd linux darwin 16 | 17 | package collector 18 | 19 | import ( 20 | "github.com/prometheus/client_golang/prometheus" 21 | ) 22 | 23 | const ( 24 | diskSubsystem = "disk" 25 | ) 26 | 27 | var ( 28 | diskLabelNames = []string{"device"} 29 | 30 | readsCompletedDesc = prometheus.NewDesc( 31 | prometheus.BuildFQName(namespace, diskSubsystem, "reads_completed_total"), 32 | "The total number of reads completed successfully.", 33 | diskLabelNames, nil, 34 | ) 35 | 36 | readBytesDesc = prometheus.NewDesc( 37 | prometheus.BuildFQName(namespace, diskSubsystem, "read_bytes_total"), 38 | "The total number of bytes read successfully.", 39 | diskLabelNames, nil, 40 | ) 41 | 42 | writesCompletedDesc = prometheus.NewDesc( 43 | prometheus.BuildFQName(namespace, diskSubsystem, "writes_completed_total"), 44 | "The total number of writes completed successfully.", 45 | diskLabelNames, nil, 46 | ) 47 | 48 | writtenBytesDesc = prometheus.NewDesc( 49 | prometheus.BuildFQName(namespace, diskSubsystem, "written_bytes_total"), 50 | "The total number of bytes written successfully.", 51 | diskLabelNames, nil, 52 | ) 53 | 54 | ioTimeSecondsDesc = prometheus.NewDesc( 55 | prometheus.BuildFQName(namespace, diskSubsystem, "io_time_seconds_total"), 56 | "Total seconds spent doing I/Os.", 57 | diskLabelNames, nil, 58 | ) 59 | 60 | readTimeSecondsDesc = prometheus.NewDesc( 61 | prometheus.BuildFQName(namespace, diskSubsystem, "read_time_seconds_total"), 62 | "The total number of seconds spent by all reads.", 63 | diskLabelNames, 64 | nil, 65 | ) 66 | 67 | writeTimeSecondsDesc = prometheus.NewDesc( 68 | prometheus.BuildFQName(namespace, diskSubsystem, "write_time_seconds_total"), 69 | "This is the total number of seconds spent by all writes.", 70 | diskLabelNames, 71 | nil, 72 | ) 73 | ) 74 | -------------------------------------------------------------------------------- /collector/diskstats_linux_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package collector 15 | 16 | import ( 17 | "os" 18 | "testing" 19 | ) 20 | 21 | func TestDiskStats(t *testing.T) { 22 | file, err := os.Open("fixtures/proc/diskstats") 23 | if err != nil { 24 | t.Fatal(err) 25 | } 26 | defer file.Close() 27 | 28 | diskStats, err := parseDiskStats(file) 29 | if err != nil { 30 | t.Fatal(err) 31 | } 32 | 33 | if want, got := "25353629", diskStats["sda4"][0]; want != got { 34 | t.Errorf("want diskstats sda4 %s, got %s", want, got) 35 | } 36 | 37 | if want, got := "68", diskStats["mmcblk0p2"][10]; want != got { 38 | t.Errorf("want diskstats mmcblk0p2 %s, got %s", want, got) 39 | } 40 | 41 | if want, got := "11130", diskStats["sdb"][14]; want != got { 42 | t.Errorf("want diskstats sdb %s, got %s", want, got) 43 | } 44 | 45 | if want, got := "1555", diskStats["sdc"][15]; want != got { 46 | t.Errorf("want diskstats sdc %s, got %s", want, got) 47 | } 48 | 49 | if want, got := "1944", diskStats["sdc"][16]; want != got { 50 | t.Errorf("want diskstats sdc %s, got %s", want, got) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /collector/diskstats_openbsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !nodiskstats 15 | 16 | package collector 17 | 18 | import ( 19 | "unsafe" 20 | 21 | "github.com/go-kit/kit/log" 22 | "github.com/prometheus/client_golang/prometheus" 23 | "golang.org/x/sys/unix" 24 | ) 25 | 26 | /* 27 | #include 28 | #include 29 | */ 30 | import "C" 31 | 32 | type diskstatsCollector struct { 33 | rxfer typedDesc 34 | rbytes typedDesc 35 | wxfer typedDesc 36 | wbytes typedDesc 37 | time typedDesc 38 | logger log.Logger 39 | } 40 | 41 | func init() { 42 | registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector) 43 | } 44 | 45 | // NewDiskstatsCollector returns a new Collector exposing disk device stats. 46 | func NewDiskstatsCollector(logger log.Logger) (Collector, error) { 47 | return &diskstatsCollector{ 48 | rxfer: typedDesc{readsCompletedDesc, prometheus.CounterValue}, 49 | rbytes: typedDesc{readBytesDesc, prometheus.CounterValue}, 50 | wxfer: typedDesc{writesCompletedDesc, prometheus.CounterValue}, 51 | wbytes: typedDesc{writtenBytesDesc, prometheus.CounterValue}, 52 | time: typedDesc{ioTimeSecondsDesc, prometheus.CounterValue}, 53 | logger: logger, 54 | }, nil 55 | } 56 | 57 | func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) (err error) { 58 | diskstatsb, err := unix.SysctlRaw("hw.diskstats") 59 | if err != nil { 60 | return err 61 | } 62 | 63 | ndisks := len(diskstatsb) / C.sizeof_struct_diskstats 64 | diskstats := *(*[]C.struct_diskstats)(unsafe.Pointer(&diskstatsb)) 65 | 66 | for i := 0; i < ndisks; i++ { 67 | diskname := C.GoString(&diskstats[i].ds_name[0]) 68 | 69 | ch <- c.rxfer.mustNewConstMetric(float64(diskstats[i].ds_rxfer), diskname) 70 | ch <- c.rbytes.mustNewConstMetric(float64(diskstats[i].ds_rbytes), diskname) 71 | ch <- c.wxfer.mustNewConstMetric(float64(diskstats[i].ds_wxfer), diskname) 72 | ch <- c.wbytes.mustNewConstMetric(float64(diskstats[i].ds_wbytes), diskname) 73 | time := float64(diskstats[i].ds_time.tv_sec) + float64(diskstats[i].ds_time.tv_usec)/1000000 74 | ch <- c.time.mustNewConstMetric(time, diskname) 75 | } 76 | return nil 77 | } 78 | -------------------------------------------------------------------------------- /collector/entropy_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !noentropy 15 | 16 | package collector 17 | 18 | import ( 19 | "fmt" 20 | 21 | "github.com/go-kit/kit/log" 22 | "github.com/prometheus/client_golang/prometheus" 23 | ) 24 | 25 | type entropyCollector struct { 26 | entropyAvail *prometheus.Desc 27 | logger log.Logger 28 | } 29 | 30 | func init() { 31 | registerCollector("entropy", defaultEnabled, NewEntropyCollector) 32 | } 33 | 34 | // NewEntropyCollector returns a new Collector exposing entropy stats. 35 | func NewEntropyCollector(logger log.Logger) (Collector, error) { 36 | return &entropyCollector{ 37 | entropyAvail: prometheus.NewDesc( 38 | prometheus.BuildFQName(namespace, "", "entropy_available_bits"), 39 | "Bits of available entropy.", 40 | nil, nil, 41 | ), 42 | logger: logger, 43 | }, nil 44 | } 45 | 46 | func (c *entropyCollector) Update(ch chan<- prometheus.Metric) error { 47 | value, err := readUintFromFile(procFilePath("sys/kernel/random/entropy_avail")) 48 | if err != nil { 49 | return fmt.Errorf("couldn't get entropy_avail: %w", err) 50 | } 51 | ch <- prometheus.MustNewConstMetric( 52 | c.entropyAvail, prometheus.GaugeValue, float64(value)) 53 | 54 | return nil 55 | } 56 | -------------------------------------------------------------------------------- /collector/filefd_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !nofilefd 15 | 16 | package collector 17 | 18 | import ( 19 | "bytes" 20 | "fmt" 21 | "io/ioutil" 22 | "os" 23 | "strconv" 24 | 25 | "github.com/go-kit/kit/log" 26 | "github.com/prometheus/client_golang/prometheus" 27 | ) 28 | 29 | const ( 30 | fileFDStatSubsystem = "filefd" 31 | ) 32 | 33 | type fileFDStatCollector struct { 34 | logger log.Logger 35 | } 36 | 37 | func init() { 38 | registerCollector(fileFDStatSubsystem, defaultEnabled, NewFileFDStatCollector) 39 | } 40 | 41 | // NewFileFDStatCollector returns a new Collector exposing file-nr stats. 42 | func NewFileFDStatCollector(logger log.Logger) (Collector, error) { 43 | return &fileFDStatCollector{logger}, nil 44 | } 45 | 46 | func (c *fileFDStatCollector) Update(ch chan<- prometheus.Metric) error { 47 | fileFDStat, err := parseFileFDStats(procFilePath("sys/fs/file-nr")) 48 | if err != nil { 49 | return fmt.Errorf("couldn't get file-nr: %w", err) 50 | } 51 | for name, value := range fileFDStat { 52 | v, err := strconv.ParseFloat(value, 64) 53 | if err != nil { 54 | return fmt.Errorf("invalid value %s in file-nr: %w", value, err) 55 | } 56 | ch <- prometheus.MustNewConstMetric( 57 | prometheus.NewDesc( 58 | prometheus.BuildFQName(namespace, fileFDStatSubsystem, name), 59 | fmt.Sprintf("File descriptor statistics: %s.", name), 60 | nil, nil, 61 | ), 62 | prometheus.GaugeValue, v, 63 | ) 64 | } 65 | return nil 66 | } 67 | 68 | func parseFileFDStats(filename string) (map[string]string, error) { 69 | file, err := os.Open(filename) 70 | if err != nil { 71 | return nil, err 72 | } 73 | defer file.Close() 74 | 75 | content, err := ioutil.ReadAll(file) 76 | if err != nil { 77 | return nil, err 78 | } 79 | parts := bytes.Split(bytes.TrimSpace(content), []byte("\u0009")) 80 | if len(parts) < 3 { 81 | return nil, fmt.Errorf("unexpected number of file stats in %q", filename) 82 | } 83 | 84 | var fileFDStat = map[string]string{} 85 | // The file-nr proc is only 1 line with 3 values. 86 | fileFDStat["allocated"] = string(parts[0]) 87 | // The second value is skipped as it will always be zero in linux 2.6. 88 | fileFDStat["maximum"] = string(parts[2]) 89 | 90 | return fileFDStat, nil 91 | } 92 | -------------------------------------------------------------------------------- /collector/filefd_linux_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package collector 15 | 16 | import "testing" 17 | 18 | func TestFileFDStats(t *testing.T) { 19 | fileFDStats, err := parseFileFDStats("fixtures/proc/sys/fs/file-nr") 20 | if err != nil { 21 | t.Fatal(err) 22 | } 23 | 24 | if want, got := "1024", fileFDStats["allocated"]; want != got { 25 | t.Errorf("want filefd allocated %q, got %q", want, got) 26 | } 27 | 28 | if want, got := "1631329", fileFDStats["maximum"]; want != got { 29 | t.Errorf("want filefd maximum %q, got %q", want, got) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /collector/filesystem_bsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build openbsd darwin,amd64 dragonfly 15 | // +build !nofilesystem 16 | 17 | package collector 18 | 19 | import ( 20 | "errors" 21 | "unsafe" 22 | 23 | "github.com/go-kit/kit/log/level" 24 | ) 25 | 26 | /* 27 | #include 28 | #include 29 | #include 30 | #include 31 | */ 32 | import "C" 33 | 34 | const ( 35 | defIgnoredMountPoints = "^/(dev)($|/)" 36 | defIgnoredFSTypes = "^devfs$" 37 | readOnly = 0x1 // MNT_RDONLY 38 | ) 39 | 40 | // Expose filesystem fullness. 41 | func (c *filesystemCollector) GetStats() (stats []filesystemStats, err error) { 42 | var mntbuf *C.struct_statfs 43 | count := C.getmntinfo(&mntbuf, C.MNT_NOWAIT) 44 | if count == 0 { 45 | return nil, errors.New("getmntinfo() failed") 46 | } 47 | 48 | mnt := (*[1 << 20]C.struct_statfs)(unsafe.Pointer(mntbuf)) 49 | stats = []filesystemStats{} 50 | for i := 0; i < int(count); i++ { 51 | mountpoint := C.GoString(&mnt[i].f_mntonname[0]) 52 | if c.ignoredMountPointsPattern.MatchString(mountpoint) { 53 | level.Debug(c.logger).Log("msg", "Ignoring mount point", "mountpoint", mountpoint) 54 | continue 55 | } 56 | 57 | device := C.GoString(&mnt[i].f_mntfromname[0]) 58 | fstype := C.GoString(&mnt[i].f_fstypename[0]) 59 | if c.ignoredFSTypesPattern.MatchString(fstype) { 60 | level.Debug(c.logger).Log("msg", "Ignoring fs type", "type", fstype) 61 | continue 62 | } 63 | 64 | var ro float64 65 | if (mnt[i].f_flags & readOnly) != 0 { 66 | ro = 1 67 | } 68 | 69 | stats = append(stats, filesystemStats{ 70 | labels: filesystemLabels{ 71 | device: device, 72 | mountPoint: rootfsStripPrefix(mountpoint), 73 | fsType: fstype, 74 | }, 75 | size: float64(mnt[i].f_blocks) * float64(mnt[i].f_bsize), 76 | free: float64(mnt[i].f_bfree) * float64(mnt[i].f_bsize), 77 | avail: float64(mnt[i].f_bavail) * float64(mnt[i].f_bsize), 78 | files: float64(mnt[i].f_files), 79 | filesFree: float64(mnt[i].f_ffree), 80 | ro: ro, 81 | }) 82 | } 83 | return stats, nil 84 | } 85 | -------------------------------------------------------------------------------- /collector/filesystem_freebsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !nofilesystem 15 | 16 | package collector 17 | 18 | import ( 19 | "github.com/go-kit/kit/log/level" 20 | "golang.org/x/sys/unix" 21 | ) 22 | 23 | const ( 24 | defIgnoredMountPoints = "^/(dev)($|/)" 25 | defIgnoredFSTypes = "^devfs$" 26 | readOnly = 0x1 // MNT_RDONLY 27 | noWait = 0x2 // MNT_NOWAIT 28 | ) 29 | 30 | // Expose filesystem fullness. 31 | func (c *filesystemCollector) GetStats() ([]filesystemStats, error) { 32 | n, err := unix.Getfsstat(nil, noWait) 33 | if err != nil { 34 | return nil, err 35 | } 36 | buf := make([]unix.Statfs_t, n) 37 | _, err = unix.Getfsstat(buf, noWait) 38 | if err != nil { 39 | return nil, err 40 | } 41 | stats := []filesystemStats{} 42 | for _, fs := range buf { 43 | mountpoint := bytesToString(fs.Mntonname[:]) 44 | if c.ignoredMountPointsPattern.MatchString(mountpoint) { 45 | level.Debug(c.logger).Log("msg", "Ignoring mount point", "mountpoint", mountpoint) 46 | continue 47 | } 48 | 49 | device := bytesToString(fs.Mntfromname[:]) 50 | fstype := bytesToString(fs.Fstypename[:]) 51 | if c.ignoredFSTypesPattern.MatchString(fstype) { 52 | level.Debug(c.logger).Log("msg", "Ignoring fs type", "type", fstype) 53 | continue 54 | } 55 | 56 | var ro float64 57 | if (fs.Flags & readOnly) != 0 { 58 | ro = 1 59 | } 60 | 61 | stats = append(stats, filesystemStats{ 62 | labels: filesystemLabels{ 63 | device: device, 64 | mountPoint: rootfsStripPrefix(mountpoint), 65 | fsType: fstype, 66 | }, 67 | size: float64(fs.Blocks) * float64(fs.Bsize), 68 | free: float64(fs.Bfree) * float64(fs.Bsize), 69 | avail: float64(fs.Bavail) * float64(fs.Bsize), 70 | files: float64(fs.Files), 71 | filesFree: float64(fs.Ffree), 72 | ro: ro, 73 | }) 74 | } 75 | return stats, nil 76 | } 77 | -------------------------------------------------------------------------------- /collector/fixtures/ip_vs_result_lbs_local_address_local_port.txt: -------------------------------------------------------------------------------- 1 | # HELP node_ipvs_backend_connections_active The current active connections by local and remote address. 2 | # TYPE node_ipvs_backend_connections_active gauge 3 | node_ipvs_backend_connections_active{local_address="",local_port="0"} 385 4 | node_ipvs_backend_connections_active{local_address="192.168.0.22",local_port="3306"} 744 5 | node_ipvs_backend_connections_active{local_address="192.168.0.55",local_port="3306"} 0 6 | node_ipvs_backend_connections_active{local_address="192.168.0.57",local_port="3306"} 2997 7 | # HELP node_ipvs_backend_connections_inactive The current inactive connections by local and remote address. 8 | # TYPE node_ipvs_backend_connections_inactive gauge 9 | node_ipvs_backend_connections_inactive{local_address="",local_port="0"} 6 10 | node_ipvs_backend_connections_inactive{local_address="192.168.0.22",local_port="3306"} 5 11 | node_ipvs_backend_connections_inactive{local_address="192.168.0.55",local_port="3306"} 0 12 | node_ipvs_backend_connections_inactive{local_address="192.168.0.57",local_port="3306"} 0 13 | # HELP node_ipvs_backend_weight The current backend weight by local and remote address. 14 | # TYPE node_ipvs_backend_weight gauge 15 | node_ipvs_backend_weight{local_address="",local_port="0"} 120 16 | node_ipvs_backend_weight{local_address="192.168.0.22",local_port="3306"} 300 17 | node_ipvs_backend_weight{local_address="192.168.0.55",local_port="3306"} 100 18 | node_ipvs_backend_weight{local_address="192.168.0.57",local_port="3306"} 200 19 | # HELP node_ipvs_connections_total The total number of connections made. 20 | # TYPE node_ipvs_connections_total counter 21 | node_ipvs_connections_total 2.3765872e+07 22 | # HELP node_ipvs_incoming_bytes_total The total amount of incoming data. 23 | # TYPE node_ipvs_incoming_bytes_total counter 24 | node_ipvs_incoming_bytes_total 8.9991519156915e+13 25 | # HELP node_ipvs_incoming_packets_total The total number of incoming packets. 26 | # TYPE node_ipvs_incoming_packets_total counter 27 | node_ipvs_incoming_packets_total 3.811989221e+09 28 | # HELP node_ipvs_outgoing_bytes_total The total amount of outgoing data. 29 | # TYPE node_ipvs_outgoing_bytes_total counter 30 | node_ipvs_outgoing_bytes_total 0 31 | # HELP node_ipvs_outgoing_packets_total The total number of outgoing packets. 32 | # TYPE node_ipvs_outgoing_packets_total counter 33 | node_ipvs_outgoing_packets_total 0 34 | -------------------------------------------------------------------------------- /collector/fixtures/ip_vs_result_lbs_local_port.txt: -------------------------------------------------------------------------------- 1 | # HELP node_ipvs_backend_connections_active The current active connections by local and remote address. 2 | # TYPE node_ipvs_backend_connections_active gauge 3 | node_ipvs_backend_connections_active{local_port="0"} 385 4 | node_ipvs_backend_connections_active{local_port="3306"} 3741 5 | # HELP node_ipvs_backend_connections_inactive The current inactive connections by local and remote address. 6 | # TYPE node_ipvs_backend_connections_inactive gauge 7 | node_ipvs_backend_connections_inactive{local_port="0"} 6 8 | node_ipvs_backend_connections_inactive{local_port="3306"} 5 9 | # HELP node_ipvs_backend_weight The current backend weight by local and remote address. 10 | # TYPE node_ipvs_backend_weight gauge 11 | node_ipvs_backend_weight{local_port="0"} 120 12 | node_ipvs_backend_weight{local_port="3306"} 600 13 | # HELP node_ipvs_connections_total The total number of connections made. 14 | # TYPE node_ipvs_connections_total counter 15 | node_ipvs_connections_total 2.3765872e+07 16 | # HELP node_ipvs_incoming_bytes_total The total amount of incoming data. 17 | # TYPE node_ipvs_incoming_bytes_total counter 18 | node_ipvs_incoming_bytes_total 8.9991519156915e+13 19 | # HELP node_ipvs_incoming_packets_total The total number of incoming packets. 20 | # TYPE node_ipvs_incoming_packets_total counter 21 | node_ipvs_incoming_packets_total 3.811989221e+09 22 | # HELP node_ipvs_outgoing_bytes_total The total amount of outgoing data. 23 | # TYPE node_ipvs_outgoing_bytes_total counter 24 | node_ipvs_outgoing_bytes_total 0 25 | # HELP node_ipvs_outgoing_packets_total The total number of outgoing packets. 26 | # TYPE node_ipvs_outgoing_packets_total counter 27 | node_ipvs_outgoing_packets_total 0 28 | -------------------------------------------------------------------------------- /collector/fixtures/ip_vs_result_lbs_none.txt: -------------------------------------------------------------------------------- 1 | # HELP node_ipvs_backend_connections_active The current active connections by local and remote address. 2 | # TYPE node_ipvs_backend_connections_active gauge 3 | node_ipvs_backend_connections_active 4126 4 | # HELP node_ipvs_backend_connections_inactive The current inactive connections by local and remote address. 5 | # TYPE node_ipvs_backend_connections_inactive gauge 6 | node_ipvs_backend_connections_inactive 11 7 | # HELP node_ipvs_backend_weight The current backend weight by local and remote address. 8 | # TYPE node_ipvs_backend_weight gauge 9 | node_ipvs_backend_weight 720 10 | # HELP node_ipvs_connections_total The total number of connections made. 11 | # TYPE node_ipvs_connections_total counter 12 | node_ipvs_connections_total 2.3765872e+07 13 | # HELP node_ipvs_incoming_bytes_total The total amount of incoming data. 14 | # TYPE node_ipvs_incoming_bytes_total counter 15 | node_ipvs_incoming_bytes_total 8.9991519156915e+13 16 | # HELP node_ipvs_incoming_packets_total The total number of incoming packets. 17 | # TYPE node_ipvs_incoming_packets_total counter 18 | node_ipvs_incoming_packets_total 3.811989221e+09 19 | # HELP node_ipvs_outgoing_bytes_total The total amount of outgoing data. 20 | # TYPE node_ipvs_outgoing_bytes_total counter 21 | node_ipvs_outgoing_bytes_total 0 22 | # HELP node_ipvs_outgoing_packets_total The total number of outgoing packets. 23 | # TYPE node_ipvs_outgoing_packets_total counter 24 | node_ipvs_outgoing_packets_total 0 25 | -------------------------------------------------------------------------------- /collector/fixtures/proc/1/mounts: -------------------------------------------------------------------------------- 1 | rootfs / rootfs rw 0 0 2 | sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0 3 | proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0 4 | udev /dev devtmpfs rw,relatime,size=10240k,nr_inodes=1008585,mode=755 0 0 5 | devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0 6 | tmpfs /run tmpfs rw,nosuid,relatime,size=1617716k,mode=755 0 0 7 | /dev/dm-2 / ext4 rw,relatime,errors=remount-ro,data=ordered 0 0 8 | securityfs /sys/kernel/security securityfs rw,nosuid,nodev,noexec,relatime 0 0 9 | tmpfs /dev/shm tmpfs rw,nosuid,nodev 0 0 10 | tmpfs /run/lock tmpfs rw,nosuid,nodev,noexec,relatime,size=5120k 0 0 11 | tmpfs /sys/fs/cgroup tmpfs ro,nosuid,nodev,noexec,mode=755 0 0 12 | cgroup /sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd 0 0 13 | pstore /sys/fs/pstore pstore rw,nosuid,nodev,noexec,relatime 0 0 14 | cgroup /sys/fs/cgroup/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0 15 | cgroup /sys/fs/cgroup/cpu,cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpu,cpuacct 0 0 16 | cgroup /sys/fs/cgroup/devices cgroup rw,nosuid,nodev,noexec,relatime,devices 0 0 17 | cgroup /sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0 18 | cgroup /sys/fs/cgroup/net_cls,net_prio cgroup rw,nosuid,nodev,noexec,relatime,net_cls,net_prio 0 0 19 | cgroup /sys/fs/cgroup/blkio cgroup rw,nosuid,nodev,noexec,relatime,blkio 0 0 20 | cgroup /sys/fs/cgroup/perf_event cgroup rw,nosuid,nodev,noexec,relatime,perf_event 0 0 21 | systemd-1 /proc/sys/fs/binfmt_misc autofs rw,relatime,fd=22,pgrp=1,timeout=300,minproto=5,maxproto=5,direct 0 0 22 | mqueue /dev/mqueue mqueue rw,relatime 0 0 23 | debugfs /sys/kernel/debug debugfs rw,relatime 0 0 24 | hugetlbfs /dev/hugepages hugetlbfs rw,relatime 0 0 25 | fusectl /sys/fs/fuse/connections fusectl rw,relatime 0 0 26 | /dev/sda3 /boot ext2 rw,relatime 0 0 27 | rpc_pipefs /run/rpc_pipefs rpc_pipefs rw,relatime 0 0 28 | binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc rw,relatime 0 0 29 | tmpfs /run/user/1000 tmpfs rw,nosuid,nodev,relatime,size=808860k,mode=700,uid=1000,gid=1000 0 0 30 | gvfsd-fuse /run/user/1000/gvfs fuse.gvfsd-fuse rw,nosuid,nodev,relatime,user_id=1000,group_id=1000 0 0 31 | /dev/sda /var/lib/kubelet/plugins/kubernetes.io/vsphere-volume/mounts/[vsanDatastore]\040bafb9e5a-8856-7e6c-699c-801844e77a4a/kubernetes-dynamic-pvc-3eba5bba-48a3-11e8-89ab-005056b92113.vmdk ext4 rw,relatime,data=ordered 0 0 32 | /dev/sda /var/lib/kubelet/plugins/kubernetes.io/vsphere-volume/mounts/[vsanDatastore]\011bafb9e5a-8856-7e6c-699c-801844e77a4a/kubernetes-dynamic-pvc-3eba5bba-48a3-11e8-89ab-005056b92113.vmdk ext4 rw,relatime,data=ordered 0 0 33 | -------------------------------------------------------------------------------- /collector/fixtures/proc/10/mountinfo: -------------------------------------------------------------------------------- 1 | 1 1 0:5 / /root rw,nosuid shared:8 - rootfs rootfs rw 2 | 16 21 0:16 / /sys rw,nosuid,nodev,noexec,relatime shared:7 - sysfs sysfs rw 3 | 17 21 0:4 / /proc rw,nosuid,nodev,noexec,relatime shared:12 - proc proc rw 4 | 21 0 8:1 / / rw,relatime shared:1 - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered 5 | 194 21 0:42 / /mnt/nfs/test rw shared:144 - nfs4 192.168.1.1:/srv/test rw,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.5,addr=192.168.1.1,local_lock=none 6 | 177 21 0:42 / /mnt/nfs/test rw shared:130 - nfs4 192.168.1.1:/srv/test rw,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.5,addr=192.168.1.1,local_lock=none 7 | 1398 798 0:44 / /mnt/nfs/test rw,relatime shared:1154 - nfs 192.168.1.1:/srv/test rw,vers=3,rsize=32768,wsize=32768,namlen=255,hard,proto=udp,timeo=11,retrans=3,sec=sys,mountaddr=192.168.1.1,mountvers=3,mountport=49602,mountproto=udp,local_lock=none,addr=192.168.1.1 8 | -------------------------------------------------------------------------------- /collector/fixtures/proc/10/mountstats: -------------------------------------------------------------------------------- 1 | device rootfs mounted on / with fstype rootfs 2 | device sysfs mounted on /sys with fstype sysfs 3 | device proc mounted on /proc with fstype proc 4 | device /dev/sda1 mounted on / with fstype ext4 5 | device 192.168.1.1:/srv/test mounted on /mnt/nfs/test with fstype nfs4 statvers=1.1 6 | opts: rw,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.5,local_lock=none 7 | age: 13968 8 | caps: caps=0xfff7,wtmult=512,dtsize=32768,bsize=0,namlen=255 9 | nfsv4: bm0=0xfdffafff,bm1=0xf9be3e,bm2=0x0,acl=0x0,pnfs=not configured 10 | sec: flavor=1,pseudoflavor=1 11 | events: 52 226 0 0 1 13 398 0 0 331 0 47 0 0 77 0 0 77 0 0 0 0 0 0 0 0 0 12 | bytes: 1207640230 0 0 0 1210214218 0 295483 0 13 | RPC iostats version: 1.0 p/v: 100003/4 (nfs) 14 | xprt: tcp 832 0 1 0 11 6428 6428 0 12154 0 24 26 5726 15 | per-op statistics 16 | NULL: 0 0 0 0 0 0 0 0 17 | READ: 1298 1298 0 207680 1210292152 6 79386 79407 18 | WRITE: 0 0 0 0 0 0 0 0 19 | 20 | device 192.168.1.1:/srv/test mounted on /mnt/nfs/test-dupe with fstype nfs4 statvers=1.1 21 | opts: rw,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.5,local_lock=none 22 | age: 13968 23 | caps: caps=0xfff7,wtmult=512,dtsize=32768,bsize=0,namlen=255 24 | nfsv4: bm0=0xfdffafff,bm1=0xf9be3e,bm2=0x0,acl=0x0,pnfs=not configured 25 | sec: flavor=1,pseudoflavor=1 26 | events: 52 226 0 0 1 13 398 0 0 331 0 47 0 0 77 0 0 77 0 0 0 0 0 0 0 0 0 27 | bytes: 1207640230 0 0 0 1210214218 0 295483 0 28 | RPC iostats version: 1.0 p/v: 100003/4 (nfs) 29 | xprt: tcp 832 0 1 0 11 6428 6428 0 12154 0 24 26 5726 30 | per-op statistics 31 | NULL: 0 0 0 0 0 0 0 0 32 | READ: 1298 1298 0 207680 1210292152 6 79386 79407 33 | WRITE: 0 0 0 0 0 0 0 0 34 | ACCESS: 2927395007 2927394995 0 526931094212 362996810236 18446743919241604546 1667369447 1953587717 35 | 36 | device 192.168.1.1:/srv/test mounted on /mnt/nfs/test-dupe with fstype nfs statvers=1.1 37 | opts: rw,vers=3,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,hard,proto=udp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.5,local_lock=none,mountaddr=192.168.1.1,mountproto=udp,mountport=47853 38 | age: 13968 39 | caps: caps=0xfff7,wtmult=512,dtsize=32768,bsize=0,namlen=255 40 | nfsv4: bm0=0xfdffafff,bm1=0xf9be3e,bm2=0x0,acl=0x0,pnfs=not configured 41 | sec: flavor=1,pseudoflavor=1 42 | events: 52 226 0 0 1 13 398 0 0 331 0 47 0 0 77 0 0 77 0 0 0 0 0 0 0 0 0 43 | bytes: 1207640230 0 0 0 1210214218 0 295483 0 44 | RPC iostats version: 1.0 p/v: 100003/4 (nfs) 45 | xprt: udp 832 0 6428 6428 0 12154 0 24 26 5726 46 | per-op statistics 47 | NULL: 0 0 0 0 0 0 0 0 48 | READ: 1298 1298 0 207680 1210292152 6 79386 79407 49 | WRITE: 0 0 0 0 0 0 0 0 50 | ACCESS: 2927395007 2927394995 0 526931094212 362996810236 18446743919241604546 1667369447 1953587717 51 | -------------------------------------------------------------------------------- /collector/fixtures/proc/10/stat: -------------------------------------------------------------------------------- 1 | 17 (khungtaskd) S 2 0 0 0 -1 2129984 0 0 0 0 14 0 0 0 20 0 1 0 24 0 0 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 0 0 0 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------------------------------------------------------------------------------- /collector/fixtures/proc/11/.missing_stat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twosson/fil_exporter/260c90af3b6a6b03b19620d855c85aed5a6fcc92/collector/fixtures/proc/11/.missing_stat -------------------------------------------------------------------------------- /collector/fixtures/proc/buddyinfo: -------------------------------------------------------------------------------- 1 | Node 0, zone DMA 1 0 1 0 2 1 1 0 1 1 3 2 | Node 0, zone DMA32 759 572 791 475 194 45 12 0 0 0 0 3 | Node 0, zone Normal 4381 1093 185 1530 567 102 4 0 0 0 0 4 | -------------------------------------------------------------------------------- /collector/fixtures/proc/drbd: -------------------------------------------------------------------------------- 1 | version: 8.4.3 (api:1/proto:86-101) 2 | srcversion: 1A9F77B1CA5FF92235C2213 3 | 4 | 1: cs:Connected ro:Primary/Primary ds:UpToDate/UpToDate C r----- 5 | ns:17324442 nr:10961011 dw:28263521 dr:118696670 al:1100 bm:221 lo:12345 pe:12346 ua:12347 ap:12348 ep:1 wo:d oos:12349 6 | -------------------------------------------------------------------------------- /collector/fixtures/proc/interrupts: -------------------------------------------------------------------------------- 1 | CPU0 CPU1 CPU2 CPU3 2 | 0: 18 0 0 0 IR-IO-APIC-edge timer 3 | 1: 17960 105 28 28 IR-IO-APIC-edge i8042 4 | 8: 1 0 0 0 IR-IO-APIC-edge rtc0 5 | 9: 398553 2320 824 863 IR-IO-APIC-fasteoi acpi 6 | 12: 380847 1021 240 198 IR-IO-APIC-edge i8042 7 | 16: 328511 322879 293782 351412 IR-IO-APIC-fasteoi ehci_hcd:usb1, mmc0 8 | 23: 1451445 3333499 1092032 2644609 IR-IO-APIC-fasteoi ehci_hcd:usb2 9 | 40: 0 0 0 0 DMAR_MSI-edge dmar0 10 | 41: 0 0 0 0 DMAR_MSI-edge dmar1 11 | 42: 378324 1734637 440240 2434308 IR-PCI-MSI-edge xhci_hcd 12 | 43: 7434032 8092205 6478877 7492252 IR-PCI-MSI-edge ahci 13 | 44: 140636 226313 347 633 IR-PCI-MSI-edge i915 14 | 45: 4 22 0 0 IR-PCI-MSI-edge mei_me 15 | 46: 43078464 130 460171 290 IR-PCI-MSI-edge iwlwifi 16 | 47: 350 224 0 0 IR-PCI-MSI-edge snd_hda_intel 17 | NMI: 47 5031 6211 4968 Non-maskable interrupts 18 | LOC: 174326351 135776678 168393257 130980079 Local timer interrupts 19 | SPU: 0 0 0 0 Spurious interrupts 20 | PMI: 47 5031 6211 4968 Performance monitoring interrupts 21 | IWI: 1509379 2411776 1512975 2428828 IRQ work interrupts 22 | RTR: 0 0 0 0 APIC ICR read retries 23 | RES: 10847134 9111507 15999335 7457260 Rescheduling interrupts 24 | CAL: 148554 157441 142912 155528 Function call interrupts 25 | TLB: 10460334 9918429 10494258 10345022 TLB shootdowns 26 | TRM: 0 0 0 0 Thermal event interrupts 27 | THR: 0 0 0 0 Threshold APIC interrupts 28 | MCE: 0 0 0 0 Machine check exceptions 29 | MCP: 2406 2399 2399 2399 Machine check polls 30 | ERR: 0 31 | MIS: 0 32 | -------------------------------------------------------------------------------- /collector/fixtures/proc/loadavg: -------------------------------------------------------------------------------- 1 | 0.21 0.37 0.39 1/719 19737 2 | -------------------------------------------------------------------------------- /collector/fixtures/proc/mdstat: -------------------------------------------------------------------------------- 1 | Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10] 2 | 3 | md3 : active raid6 sda1[8] sdh1[7] sdg1[6] sdf1[5] sde1[11] sdd1[3] sdc1[10] sdb1[9] sdd1[10](S) sdd2[11](S) 4 | 5853468288 blocks super 1.2 level 6, 64k chunk, algorithm 2 [8/8] [UUUUUUUU] 5 | 6 | md127 : active raid1 sdi2[0] sdj2[1] 7 | 312319552 blocks [2/2] [UU] 8 | 9 | md0 : active raid1 sdi1[0] sdj1[1] 10 | 248896 blocks [2/2] [UU] 11 | 12 | md4 : inactive raid1 sda3[0](F) sdb3[1](S) 13 | 4883648 blocks [2/2] [UU] 14 | 15 | md6 : active raid1 sdb2[2](F) sdc[1](S) sda2[0] 16 | 195310144 blocks [2/1] [U_] 17 | [=>...................] recovery = 8.5% (16775552/195310144) finish=17.0min speed=259783K/sec 18 | 19 | md8 : active raid1 sdb1[1] sda1[0] sdc[2](S) sde[3](S) 20 | 195310144 blocks [2/2] [UU] 21 | [=>...................] resync = 8.5% (16775552/195310144) finish=17.0min speed=259783K/sec 22 | 23 | md7 : active raid6 sdb1[0] sde1[3] sdd1[2] sdc1[1](F) 24 | 7813735424 blocks super 1.2 level 6, 512k chunk, algorithm 2 [4/3] [U_UU] 25 | bitmap: 0/30 pages [0KB], 65536KB chunk 26 | 27 | md9 : active raid1 sdc2[2] sdd2[3] sdb2[1] sda2[0] sde[4](F) sdf[5](F) sdg[6](S) 28 | 523968 blocks super 1.2 [4/4] [UUUU] 29 | resync=DELAYED 30 | 31 | md10 : active raid0 sda1[0] sdb1[1] 32 | 314159265 blocks 64k chunks 33 | 34 | md11 : active (auto-read-only) raid1 sdb2[0] sdc2[1] sdc3[2](F) hda[4](S) ssdc2[3](S) 35 | 4190208 blocks super 1.2 [2/2] [UU] 36 | resync=PENDING 37 | 38 | md12 : active raid0 sdc2[0] sdd2[1] 39 | 3886394368 blocks super 1.2 512k chunks 40 | 41 | md126 : active raid0 sdb[1] sdc[0] 42 | 1855870976 blocks super external:/md127/0 128k chunks 43 | 44 | md219 : inactive sdb[2](S) sdc[1](S) sda[0](S) 45 | 7932 blocks super external:imsm 46 | 47 | md00 : active raid0 xvdb[0] 48 | 4186624 blocks super 1.2 256k chunks 49 | 50 | md120 : active linear sda1[1] sdb1[0] 51 | 2095104 blocks super 1.2 0k rounding 52 | 53 | md101 : active (read-only) raid0 sdb[2] sdd[1] sdc[0] 54 | 322560 blocks super 1.2 512k chunks 55 | 56 | unused devices: 57 | -------------------------------------------------------------------------------- /collector/fixtures/proc/meminfo: -------------------------------------------------------------------------------- 1 | MemTotal: 3742148 kB 2 | MemFree: 225472 kB 3 | Buffers: 22040 kB 4 | Cached: 930888 kB 5 | SwapCached: 192504 kB 6 | Active: 2233416 kB 7 | Inactive: 1028728 kB 8 | Active(anon): 2020004 kB 9 | Inactive(anon): 883052 kB 10 | Active(file): 213412 kB 11 | Inactive(file): 145676 kB 12 | Unevictable: 32 kB 13 | Mlocked: 32 kB 14 | SwapTotal: 4194300 kB 15 | SwapFree: 3155360 kB 16 | Dirty: 1052 kB 17 | Writeback: 0 kB 18 | AnonPages: 2244172 kB 19 | Mapped: 239220 kB 20 | Shmem: 593840 kB 21 | Slab: 98932 kB 22 | SReclaimable: 44772 kB 23 | SUnreclaim: 54160 kB 24 | KernelStack: 5800 kB 25 | PageTables: 75212 kB 26 | NFS_Unstable: 0 kB 27 | Bounce: 0 kB 28 | WritebackTmp: 0 kB 29 | CommitLimit: 6065372 kB 30 | Committed_AS: 7835436 kB 31 | VmallocTotal: 34359738367 kB 32 | VmallocUsed: 352840 kB 33 | VmallocChunk: 34359338876 kB 34 | HardwareCorrupted: 0 kB 35 | AnonHugePages: 0 kB 36 | HugePages_Total: 0 37 | HugePages_Free: 0 38 | HugePages_Rsvd: 0 39 | HugePages_Surp: 0 40 | Hugepagesize: 2048 kB 41 | DirectMap4k: 185660 kB 42 | DirectMap2M: 3698688 kB 43 | -------------------------------------------------------------------------------- /collector/fixtures/proc/net/arp: -------------------------------------------------------------------------------- 1 | IP address HW type Flags HW address Mask Device 2 | 192.168.1.1 0x1 0x2 cc:aa:dd:ee:aa:bb * eth0 3 | 192.168.1.2 0x1 0x2 bb:cc:dd:ee:ff:aa * eth0 4 | 192.168.1.3 0x1 0x2 aa:bb:cc:dd:ee:ff * eth0 5 | 192.168.1.4 0x1 0x2 dd:ee:ff:aa:bb:cc * eth1 6 | 192.168.1.5 0x1 0x2 ee:ff:aa:bb:cc:dd * eth1 7 | 192.168.1.6 0x1 0x2 ff:aa:bb:cc:dd:ee * eth1 8 | -------------------------------------------------------------------------------- /collector/fixtures/proc/net/dev: -------------------------------------------------------------------------------- 1 | Inter-| Receive | Transmit 2 | face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed 3 | tun0: 1888 24 0 0 0 0 0 0 67120 934 0 0 0 0 0 0 4 | veth4B09XN: 648 8 0 0 0 0 0 0 1943284 10640 0 0 0 0 0 0 5 | lo: 435303245 1832522 0 0 0 0 0 0 435303245 1832522 0 0 0 0 0 0 6 | eth0:68210035552 520993275 0 0 0 0 0 0 9315587528 43451486 0 0 0 0 0 0 7 | lxcbr0: 0 0 0 0 0 0 0 0 2630299 28339 0 0 0 0 0 0 8 | wlan0: 10437182923 13899359 0 0 0 0 0 0 2851649360 11726200 0 0 0 0 0 0 9 | docker0: 64910168 1065585 0 0 0 0 0 0 2681662018 1929779 0 0 0 0 0 0 10 | ibr10:30: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 | flannel.1: 18144009813 228499337 0 0 0 0 0 0 20758990068 258369223 0 64 0 0 0 0 12 | 💩0: 57750104 105557 0 0 0 0 0 72 404570255 304261 0 0 0 0 0 0 13 | -------------------------------------------------------------------------------- /collector/fixtures/proc/net/ip_vs: -------------------------------------------------------------------------------- 1 | IP Virtual Server version 1.2.1 (size=4096) 2 | Prot LocalAddress:Port Scheduler Flags 3 | -> RemoteAddress:Port Forward Weight ActiveConn InActConn 4 | TCP C0A80016:0CEA wlc 5 | -> C0A85216:0CEA Tunnel 100 248 2 6 | -> C0A85318:0CEA Tunnel 100 248 2 7 | -> C0A85315:0CEA Tunnel 100 248 1 8 | TCP C0A80039:0CEA wlc 9 | -> C0A85416:0CEA Tunnel 0 0 0 10 | -> C0A85215:0CEA Tunnel 100 1499 0 11 | -> C0A83215:0CEA Tunnel 100 1498 0 12 | TCP C0A80037:0CEA wlc 13 | -> C0A8321A:0CEA Tunnel 0 0 0 14 | -> C0A83120:0CEA Tunnel 100 0 0 15 | FWM 10001000 wlc 16 | -> C0A8321A:0CEA Tunnel 20 64 1 17 | -> C0A83120:0CEA Tunnel 100 321 5 18 | -------------------------------------------------------------------------------- /collector/fixtures/proc/net/ip_vs_stats: -------------------------------------------------------------------------------- 1 | Total Incoming Outgoing Incoming Outgoing 2 | Conns Packets Packets Bytes Bytes 3 | 16AA370 E33656E5 0 51D8C8883AB3 0 4 | 5 | Conns/s Pkts/s Pkts/s Bytes/s Bytes/s 6 | 4 1FB3C 0 1282A8F 0 7 | -------------------------------------------------------------------------------- /collector/fixtures/proc/net/netstat: -------------------------------------------------------------------------------- 1 | TcpExt: SyncookiesSent SyncookiesRecv SyncookiesFailed EmbryonicRsts PruneCalled RcvPruned OfoPruned OutOfWindowIcmps LockDroppedIcmps ArpFilter TW TWRecycled TWKilled PAWSPassive PAWSActive PAWSEstab DelayedACKs DelayedACKLocked DelayedACKLost ListenOverflows ListenDrops TCPPrequeued TCPDirectCopyFromBacklog TCPDirectCopyFromPrequeue TCPPrequeueDropped TCPHPHits TCPHPHitsToUser TCPPureAcks TCPHPAcks TCPRenoRecovery TCPSackRecovery TCPSACKReneging TCPFACKReorder TCPSACKReorder TCPRenoReorder TCPTSReorder TCPFullUndo TCPPartialUndo TCPDSACKUndo TCPLossUndo TCPLoss TCPLostRetransmit TCPRenoFailures TCPSackFailures TCPLossFailures TCPFastRetrans TCPForwardRetrans TCPSlowStartRetrans TCPTimeouts TCPRenoRecoveryFail TCPSackRecoveryFail TCPSchedulerFailed TCPRcvCollapsed TCPDSACKOldSent TCPDSACKOfoSent TCPDSACKRecv TCPDSACKOfoRecv TCPAbortOnData TCPAbortOnClose TCPAbortOnMemory TCPAbortOnTimeout TCPAbortOnLinger TCPAbortFailed TCPMemoryPressures TCPSACKDiscard TCPDSACKIgnoredOld TCPDSACKIgnoredNoUndo TCPSpuriousRTOs TCPMD5NotFound TCPMD5Unexpected TCPSackShifted TCPSackMerged TCPSackShiftFallback TCPBacklogDrop TCPMinTTLDrop TCPDeferAcceptDrop IPReversePathFilter TCPTimeWaitOverflow TCPReqQFullDoCookies TCPReqQFullDrop TCPChallengeACK TCPSYNChallenge 2 | TcpExt: 0 0 2 0 0 0 0 0 0 0 388812 0 0 0 0 6 102471 17 9 0 0 80568 0 168808 0 4471289 26 1433940 3744565 0 1 0 0 0 0 0 0 0 0 48 0 0 0 1 0 1 0 1 115 0 0 0 0 9 0 5 0 41 4 0 0 0 0 0 0 0 1 0 0 0 0 2 5 0 0 0 0 0 0 0 2 2 3 | IpExt: InNoRoutes InTruncatedPkts InMcastPkts OutMcastPkts InBcastPkts OutBcastPkts InOctets OutOctets InMcastOctets OutMcastOctets InBcastOctets OutBcastOctets 4 | IpExt: 0 0 0 0 0 0 6286396970 2786264347 0 0 0 0 5 | -------------------------------------------------------------------------------- /collector/fixtures/proc/net/rpc/nfs: -------------------------------------------------------------------------------- 1 | net 70 70 69 45 2 | rpc 1218785755 374636 1218815394 3 | proc2 18 16 57 74 52 71 73 45 86 0 52 83 61 17 53 50 23 70 82 4 | proc3 22 0 1061909262 48906 4077635 117661341 5 29391916 2570425 2993289 590 0 0 7815 15 1130 0 3983 92385 13332 2 1 23729 5 | proc4 48 98 51 54 83 85 23 24 1 28 73 68 83 12 84 39 68 59 58 88 29 74 69 96 21 84 15 53 86 54 66 56 97 36 49 32 85 81 11 58 32 67 13 28 35 90 1 26 0 6 | -------------------------------------------------------------------------------- /collector/fixtures/proc/net/rpc/nfsd: -------------------------------------------------------------------------------- 1 | rc 0 6 18622 2 | fh 0 0 0 0 0 3 | io 157286400 72864 4 | th 8 0 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 5 | ra 32 0 0 0 0 0 0 0 0 0 0 0 6 | net 972 55 917 1 7 | rpc 18628 3 1 2 0 8 | proc2 18 2 69 0 0 4410 0 0 0 0 0 0 0 0 0 0 0 99 2 9 | proc3 22 2 112 0 2719 111 0 0 0 0 0 0 0 0 0 0 0 27 216 0 2 1 0 10 | proc4 2 2 10853 11 | proc4ops 72 0 0 0 1098 2 0 0 0 0 8179 5896 0 0 0 0 5900 0 0 2 0 2 0 9609 0 2 150 1272 0 0 0 1236 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 | -------------------------------------------------------------------------------- /collector/fixtures/proc/net/snmp: -------------------------------------------------------------------------------- 1 | Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKs FragFails FragCreates 2 | Ip: 1 64 57740232 0 25 397750 0 0 57340175 55365537 0 54 0 0 0 0 0 0 0 3 | Icmp: InMsgs InErrors InCsumErrors InDestUnreachs InTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoReps InTimestamps InTimestampReps InAddrMasks InAddrMaskReps OutMsgs OutErrors OutDestUnreachs OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects OutEchos OutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutAddrMaskReps 4 | Icmp: 104 0 0 104 0 0 0 0 0 0 0 0 0 0 120 0 120 0 0 0 0 0 0 0 0 0 0 5 | IcmpMsg: InType3 OutType3 6 | IcmpMsg: 104 120 7 | Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs InErrs OutRsts InCsumErrors 8 | Tcp: 1 200 120000 -1 3556 230 341 161 0 57252008 54915039 227 5 1003 0 9 | Udp: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors InCsumErrors 10 | Udp: 88542 120 0 53028 9 8 0 11 | UdpLite: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors InCsumErrors 12 | UdpLite: 0 0 0 0 0 0 0 13 | -------------------------------------------------------------------------------- /collector/fixtures/proc/net/sockstat: -------------------------------------------------------------------------------- 1 | sockets: used 229 2 | TCP: inuse 4 orphan 0 tw 4 alloc 17 mem 1 3 | UDP: inuse 0 mem 0 4 | UDPLITE: inuse 0 5 | RAW: inuse 0 6 | FRAG: inuse 0 memory 0 7 | -------------------------------------------------------------------------------- /collector/fixtures/proc/net/sockstat6: -------------------------------------------------------------------------------- 1 | TCP6: inuse 17 2 | UDP6: inuse 9 3 | UDPLITE6: inuse 0 4 | RAW6: inuse 1 5 | FRAG6: inuse 0 memory 0 6 | -------------------------------------------------------------------------------- /collector/fixtures/proc/net/softnet_stat: -------------------------------------------------------------------------------- 1 | 00049279 00000000 00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 2 | 000dfb82 00000029 0000000a 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 3 | 00551c3f 00000000 00000055 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 4 | 002f8339 00000000 00000032 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 -------------------------------------------------------------------------------- /collector/fixtures/proc/net/tcpstat: -------------------------------------------------------------------------------- 1 | sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode 2 | 0: 00000000:0016 00000000:0000 0A 00000015:00000000 00:00000000 00000000 0 0 2740 1 ffff88003d3af3c0 100 0 0 10 0 3 | 1: 0F02000A:0016 0202000A:8B6B 01 00000015:00000001 02:000AC99B 00000000 0 0 3652 4 ffff88003d3ae040 21 4 31 47 46 4 | -------------------------------------------------------------------------------- /collector/fixtures/proc/net/udp: -------------------------------------------------------------------------------- 1 | sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode 2 | 0: 00000000:0016 00000000:0000 0A 00000015:00000000 00:00000000 00000000 0 0 2740 1 ffff88003d3af3c0 100 0 0 10 0 3 | -------------------------------------------------------------------------------- /collector/fixtures/proc/pressure/cpu: -------------------------------------------------------------------------------- 1 | some avg10=0.00 avg60=0.00 avg300=0.00 total=14036781 2 | -------------------------------------------------------------------------------- /collector/fixtures/proc/pressure/io: -------------------------------------------------------------------------------- 1 | some avg10=0.18 avg60=0.34 avg300=0.10 total=159886802 2 | full avg10=0.18 avg60=0.34 avg300=0.10 total=159229614 3 | -------------------------------------------------------------------------------- /collector/fixtures/proc/pressure/memory: -------------------------------------------------------------------------------- 1 | some avg10=0.00 avg60=0.00 avg300=0.00 total=0 2 | full avg10=0.00 avg60=0.00 avg300=0.00 total=0 3 | -------------------------------------------------------------------------------- /collector/fixtures/proc/schedstat: -------------------------------------------------------------------------------- 1 | version 15 2 | timestamp 15819019232 3 | cpu0 498494191 0 3533438552 2553969831 3853684107 2465731542 2045936778163039 343796328169361 4767485306 4 | domain0 00000000,00000003 212499247 210112015 1861015 1860405436 536440 369895 32599 210079416 25368550 24241256 384652 927363878 807233 6366 1647 24239609 2122447165 1886868564 121112060 2848625533 125678146 241025 1032026 1885836538 2545 12 2533 0 0 0 0 0 0 1387952561 21076581 0 5 | cpu1 518377256 0 4155211005 2778589869 10466382 2867629021 1904686152592476 364107263788241 5145567945 6 | domain0 00000000,00000003 217653037 215526982 1577949 1580427380 557469 393576 28538 215498444 28721913 27662819 371153 870843407 745912 5523 1639 27661180 2331056874 2107732788 111442342 652402556 123615235 196159 1045245 2106687543 2400 3 2397 0 0 0 0 0 0 1437804657 26220076 0 7 | -------------------------------------------------------------------------------- /collector/fixtures/proc/self/mountinfo: -------------------------------------------------------------------------------- 1 | 1 1 0:5 / /root rw,nosuid shared:8 - rootfs rootfs rw 2 | 16 21 0:16 / /sys rw,nosuid,nodev,noexec,relatime shared:7 - sysfs sysfs rw 3 | 17 21 0:4 / /proc rw,nosuid,nodev,noexec,relatime shared:12 - proc proc rw 4 | 21 0 8:1 / / rw,relatime shared:1 - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered 5 | 194 21 0:42 / /mnt/nfs/test rw shared:144 - nfs4 192.168.1.1:/srv/test rw,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.5,addr=192.168.1.1,local_lock=none 6 | 177 21 0:42 / /mnt/nfs/test rw shared:130 - nfs4 192.168.1.1:/srv/test rw,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.5,addr=192.168.1.1,local_lock=none 7 | 1398 798 0:44 / /mnt/nfs/test rw,relatime shared:1154 - nfs 192.168.1.1:/srv/test rw,vers=3,rsize=32768,wsize=32768,namlen=255,hard,proto=udp,timeo=11,retrans=3,sec=sys,mountaddr=192.168.1.1,mountvers=3,mountport=49602,mountproto=udp,local_lock=none,addr=192.168.1.1 8 | -------------------------------------------------------------------------------- /collector/fixtures/proc/self/mountstats: -------------------------------------------------------------------------------- 1 | device rootfs mounted on / with fstype rootfs 2 | device sysfs mounted on /sys with fstype sysfs 3 | device proc mounted on /proc with fstype proc 4 | device /dev/sda1 mounted on / with fstype ext4 5 | device 192.168.1.1:/srv/test mounted on /mnt/nfs/test with fstype nfs4 statvers=1.1 6 | opts: rw,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.5,local_lock=none 7 | age: 13968 8 | caps: caps=0xfff7,wtmult=512,dtsize=32768,bsize=0,namlen=255 9 | nfsv4: bm0=0xfdffafff,bm1=0xf9be3e,bm2=0x0,acl=0x0,pnfs=not configured 10 | sec: flavor=1,pseudoflavor=1 11 | events: 52 226 0 0 1 13 398 0 0 331 0 47 0 0 77 0 0 77 0 0 0 0 0 0 0 0 0 12 | bytes: 1207640230 0 0 0 1210214218 0 295483 0 13 | RPC iostats version: 1.0 p/v: 100003/4 (nfs) 14 | xprt: tcp 832 0 1 0 11 6428 6428 0 12154 0 24 26 5726 15 | per-op statistics 16 | NULL: 0 0 0 0 0 0 0 0 17 | READ: 1298 1298 0 207680 1210292152 6 79386 79407 18 | WRITE: 0 0 0 0 0 0 0 0 19 | 20 | device 192.168.1.1:/srv/test mounted on /mnt/nfs/test-dupe with fstype nfs4 statvers=1.1 21 | opts: rw,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.5,local_lock=none 22 | age: 13968 23 | caps: caps=0xfff7,wtmult=512,dtsize=32768,bsize=0,namlen=255 24 | nfsv4: bm0=0xfdffafff,bm1=0xf9be3e,bm2=0x0,acl=0x0,pnfs=not configured 25 | sec: flavor=1,pseudoflavor=1 26 | events: 52 226 0 0 1 13 398 0 0 331 0 47 0 0 77 0 0 77 0 0 0 0 0 0 0 0 0 27 | bytes: 1207640230 0 0 0 1210214218 0 295483 0 28 | RPC iostats version: 1.0 p/v: 100003/4 (nfs) 29 | xprt: tcp 832 0 1 0 11 6428 6428 0 12154 0 24 26 5726 30 | per-op statistics 31 | NULL: 0 0 0 0 0 0 0 0 32 | READ: 1298 1298 0 207680 1210292152 6 79386 79407 33 | WRITE: 0 0 0 0 0 0 0 0 34 | ACCESS: 2927395007 2927394995 0 526931094212 362996810236 18446743919241604546 1667369447 1953587717 35 | 36 | device 192.168.1.1:/srv/test mounted on /mnt/nfs/test-dupe with fstype nfs statvers=1.1 37 | opts: rw,vers=3,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,hard,proto=udp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.5,local_lock=none,mountaddr=192.168.1.1,mountproto=udp,mountport=47853 38 | age: 13968 39 | caps: caps=0xfff7,wtmult=512,dtsize=32768,bsize=0,namlen=255 40 | nfsv4: bm0=0xfdffafff,bm1=0xf9be3e,bm2=0x0,acl=0x0,pnfs=not configured 41 | sec: flavor=1,pseudoflavor=1 42 | events: 52 226 0 0 1 13 398 0 0 331 0 47 0 0 77 0 0 77 0 0 0 0 0 0 0 0 0 43 | bytes: 1207640230 0 0 0 1210214218 0 295483 0 44 | RPC iostats version: 1.0 p/v: 100003/4 (nfs) 45 | xprt: udp 832 0 6428 6428 0 12154 0 24 26 5726 46 | per-op statistics 47 | NULL: 0 0 0 0 0 0 0 0 48 | READ: 1298 1298 0 207680 1210292152 6 79386 79407 49 | WRITE: 0 0 0 0 0 0 0 0 50 | ACCESS: 2927395007 2927394995 0 526931094212 362996810236 18446743919241604546 1667369447 1953587717 51 | -------------------------------------------------------------------------------- /collector/fixtures/proc/self/stat: -------------------------------------------------------------------------------- 1 | 17 (khungtaskd) S 2 0 0 0 -1 2129984 0 0 0 0 14 0 0 0 20 0 1 0 24 0 0 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 0 0 0 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -------------------------------------------------------------------------------- /collector/fixtures/proc/spl/kstat/zfs/abdstats: -------------------------------------------------------------------------------- 1 | 7 1 0x01 21 5712 73163810083184 309946154984654 2 | name type data 3 | struct_size 4 2520 4 | linear_cnt 4 62 5 | linear_data_size 4 223232 6 | scatter_cnt 4 1 7 | scatter_data_size 4 16384 8 | scatter_chunk_waste 4 0 9 | scatter_order_0 4 0 10 | scatter_order_1 4 0 11 | scatter_order_2 4 1 12 | scatter_order_3 4 0 13 | scatter_order_4 4 0 14 | scatter_order_5 4 0 15 | scatter_order_6 4 0 16 | scatter_order_7 4 0 17 | scatter_order_8 4 0 18 | scatter_order_9 4 0 19 | scatter_order_10 4 0 20 | scatter_page_multi_chunk 4 0 21 | scatter_page_multi_zone 4 0 22 | scatter_page_alloc_retry 4 0 23 | scatter_sg_table_retry 4 0 24 | -------------------------------------------------------------------------------- /collector/fixtures/proc/spl/kstat/zfs/dbuf_stats: -------------------------------------------------------------------------------- 1 | 15 1 0x01 63 17136 73163812943503 309964267073187 2 | name type data 3 | dbuf_cache_count 4 27 4 | dbuf_cache_size 4 302080 5 | dbuf_cache_size_max 4 394240 6 | dbuf_cache_max_bytes 4 62834368 7 | dbuf_cache_lowater_bytes 4 56550932 8 | dbuf_cache_hiwater_bytes 4 69117804 9 | dbuf_cache_total_evicts 4 0 10 | dbuf_cache_level_0 4 27 11 | dbuf_cache_level_1 4 0 12 | dbuf_cache_level_2 4 0 13 | dbuf_cache_level_3 4 0 14 | dbuf_cache_level_4 4 0 15 | dbuf_cache_level_5 4 0 16 | dbuf_cache_level_6 4 0 17 | dbuf_cache_level_7 4 0 18 | dbuf_cache_level_8 4 0 19 | dbuf_cache_level_9 4 0 20 | dbuf_cache_level_10 4 0 21 | dbuf_cache_level_11 4 0 22 | dbuf_cache_level_0_bytes 4 302080 23 | dbuf_cache_level_1_bytes 4 0 24 | dbuf_cache_level_2_bytes 4 0 25 | dbuf_cache_level_3_bytes 4 0 26 | dbuf_cache_level_4_bytes 4 0 27 | dbuf_cache_level_5_bytes 4 0 28 | dbuf_cache_level_6_bytes 4 0 29 | dbuf_cache_level_7_bytes 4 0 30 | dbuf_cache_level_8_bytes 4 0 31 | dbuf_cache_level_9_bytes 4 0 32 | dbuf_cache_level_10_bytes 4 0 33 | dbuf_cache_level_11_bytes 4 0 34 | hash_hits 4 108807 35 | hash_misses 4 1851 36 | hash_collisions 4 0 37 | hash_elements 4 55 38 | hash_elements_max 4 55 39 | hash_chains 4 0 40 | hash_chain_max 4 0 41 | hash_insert_race 4 0 42 | hash_dbuf_level_0 4 37 43 | hash_dbuf_level_1 4 10 44 | hash_dbuf_level_2 4 2 45 | hash_dbuf_level_3 4 2 46 | hash_dbuf_level_4 4 2 47 | hash_dbuf_level_5 4 2 48 | hash_dbuf_level_6 4 0 49 | hash_dbuf_level_7 4 0 50 | hash_dbuf_level_8 4 0 51 | hash_dbuf_level_9 4 0 52 | hash_dbuf_level_10 4 0 53 | hash_dbuf_level_11 4 0 54 | hash_dbuf_level_0_bytes 4 465920 55 | hash_dbuf_level_1_bytes 4 1310720 56 | hash_dbuf_level_2_bytes 4 262144 57 | hash_dbuf_level_3_bytes 4 262144 58 | hash_dbuf_level_4_bytes 4 262144 59 | hash_dbuf_level_5_bytes 4 262144 60 | hash_dbuf_level_6_bytes 4 0 61 | hash_dbuf_level_7_bytes 4 0 62 | hash_dbuf_level_8_bytes 4 0 63 | hash_dbuf_level_9_bytes 4 0 64 | hash_dbuf_level_10_bytes 4 0 65 | hash_dbuf_level_11_bytes 4 0 66 | -------------------------------------------------------------------------------- /collector/fixtures/proc/spl/kstat/zfs/dmu_tx: -------------------------------------------------------------------------------- 1 | 5 1 0x01 11 528 8010436841 354962070418194 2 | name type data 3 | dmu_tx_assigned 4 3532844 4 | dmu_tx_delay 4 0 5 | dmu_tx_error 4 0 6 | dmu_tx_suspended 4 0 7 | dmu_tx_group 4 0 8 | dmu_tx_memory_reserve 4 0 9 | dmu_tx_memory_reclaim 4 0 10 | dmu_tx_dirty_throttle 4 0 11 | dmu_tx_dirty_delay 4 0 12 | dmu_tx_dirty_over_max 4 0 13 | dmu_tx_quota 4 0 14 | -------------------------------------------------------------------------------- /collector/fixtures/proc/spl/kstat/zfs/dnodestats: -------------------------------------------------------------------------------- 1 | 10 1 0x01 28 7616 73163810135894 309969103316276 2 | name type data 3 | dnode_hold_dbuf_hold 4 0 4 | dnode_hold_dbuf_read 4 0 5 | dnode_hold_alloc_hits 4 37617 6 | dnode_hold_alloc_misses 4 0 7 | dnode_hold_alloc_interior 4 0 8 | dnode_hold_alloc_lock_retry 4 0 9 | dnode_hold_alloc_lock_misses 4 0 10 | dnode_hold_alloc_type_none 4 0 11 | dnode_hold_free_hits 4 0 12 | dnode_hold_free_misses 4 0 13 | dnode_hold_free_lock_misses 4 0 14 | dnode_hold_free_lock_retry 4 0 15 | dnode_hold_free_overflow 4 0 16 | dnode_hold_free_refcount 4 0 17 | dnode_hold_free_txg 4 0 18 | dnode_allocate 4 0 19 | dnode_reallocate 4 0 20 | dnode_buf_evict 4 17 21 | dnode_alloc_next_chunk 4 0 22 | dnode_alloc_race 4 0 23 | dnode_alloc_next_block 4 0 24 | dnode_move_invalid 4 0 25 | dnode_move_recheck1 4 0 26 | dnode_move_recheck2 4 0 27 | dnode_move_special 4 0 28 | dnode_move_handle 4 0 29 | dnode_move_rwlock 4 0 30 | dnode_move_active 4 0 31 | -------------------------------------------------------------------------------- /collector/fixtures/proc/spl/kstat/zfs/fm: -------------------------------------------------------------------------------- 1 | 0 1 0x01 4 192 8007255140 354329591145385 2 | name type data 3 | erpt-dropped 4 18 4 | erpt-set-failed 4 0 5 | fmri-set-failed 4 0 6 | payload-set-failed 4 0 7 | -------------------------------------------------------------------------------- /collector/fixtures/proc/spl/kstat/zfs/pool1/io: -------------------------------------------------------------------------------- 1 | 12 3 0x00 1 80 79205351707403 395818011156865 2 | nread nwritten reads writes wtime wlentime wupdate rtime rlentime rupdate wcnt rcnt 3 | 1884160 3206144 22 132 7155162 104112268 79210489694949 24168078 104112268 79210489849220 0 0 4 | -------------------------------------------------------------------------------- /collector/fixtures/proc/spl/kstat/zfs/pool1/objset-1: -------------------------------------------------------------------------------- 1 | 23 1 0x01 7 2160 221578688875 6665999035587 2 | name type data 3 | dataset_name 7 pool1 4 | writes 4 0 5 | nwritten 4 0 6 | reads 4 0 7 | nread 4 0 8 | nunlinks 4 0 9 | nunlinked 4 0 10 | -------------------------------------------------------------------------------- /collector/fixtures/proc/spl/kstat/zfs/pool1/objset-2: -------------------------------------------------------------------------------- 1 | 24 1 0x01 7 2160 221611904716 7145015038451 2 | name type data 3 | dataset_name 7 pool1/dataset1 4 | writes 4 4 5 | nwritten 4 12302 6 | reads 4 2 7 | nread 4 28 8 | nunlinks 4 3 9 | nunlinked 4 3 10 | -------------------------------------------------------------------------------- /collector/fixtures/proc/spl/kstat/zfs/poolz1/io: -------------------------------------------------------------------------------- 1 | 16 3 0x00 1 80 79568650431241 395832279341621 2 | nread nwritten reads writes wtime wlentime wupdate rtime rlentime rupdate wcnt rcnt 3 | 2826240 2680501248 33 25294 9673715628 6472105124093 110734831833266 9829091640 6472105124093 110734831944501 0 0 4 | -------------------------------------------------------------------------------- /collector/fixtures/proc/spl/kstat/zfs/poolz1/objset-1: -------------------------------------------------------------------------------- 1 | 30 1 0x01 7 2160 217993779684 2621674546179 2 | name type data 3 | dataset_name 7 poolz1 4 | writes 4 0 5 | nwritten 4 0 6 | reads 4 0 7 | nread 4 0 8 | nunlinks 4 0 9 | nunlinked 4 0 -------------------------------------------------------------------------------- /collector/fixtures/proc/spl/kstat/zfs/poolz1/objset-2: -------------------------------------------------------------------------------- 1 | 31 1 0x01 7 2160 218133979890 3024169078920 2 | name type data 3 | dataset_name 7 poolz1/dataset1 4 | writes 4 10 5 | nwritten 4 32806 6 | reads 4 2 7 | nread 4 28 8 | nunlinks 4 14 9 | nunlinked 4 14 -------------------------------------------------------------------------------- /collector/fixtures/proc/spl/kstat/zfs/vdev_cache_stats: -------------------------------------------------------------------------------- 1 | 8 1 0x01 3 144 8012540758 352116106118781 2 | name type data 3 | delegations 4 40 4 | hits 4 0 5 | misses 4 0 6 | -------------------------------------------------------------------------------- /collector/fixtures/proc/spl/kstat/zfs/vdev_mirror_stats: -------------------------------------------------------------------------------- 1 | 18 1 0x01 7 1904 73163813004224 309980651991187 2 | name type data 3 | rotating_linear 4 0 4 | rotating_offset 4 0 5 | rotating_seek 4 0 6 | non_rotating_linear 4 0 7 | non_rotating_seek 4 0 8 | preferred_found 4 0 9 | preferred_not_found 4 94 10 | -------------------------------------------------------------------------------- /collector/fixtures/proc/spl/kstat/zfs/xuio_stats: -------------------------------------------------------------------------------- 1 | 2 1 0x01 6 288 8009100742 353415816865654 2 | name type data 3 | onloan_read_buf 4 32 4 | onloan_write_buf 4 0 5 | read_buf_copied 4 0 6 | read_buf_nocopy 4 0 7 | write_buf_copied 4 0 8 | write_buf_nocopy 4 0 9 | -------------------------------------------------------------------------------- /collector/fixtures/proc/spl/kstat/zfs/zfetchstats: -------------------------------------------------------------------------------- 1 | 4 1 0x01 11 528 8010434610 345692669858836 2 | name type data 3 | hits 4 7067992 4 | misses 4 11 5 | colinear_hits 4 0 6 | colinear_misses 4 11 7 | stride_hits 4 7067990 8 | stride_misses 4 0 9 | reclaim_successes 4 0 10 | reclaim_failures 4 11 11 | streams_resets 4 0 12 | streams_noresets 4 2 13 | bogus_streams 4 0 14 | -------------------------------------------------------------------------------- /collector/fixtures/proc/spl/kstat/zfs/zil: -------------------------------------------------------------------------------- 1 | 7 1 0x01 13 624 8012538347 351689526932992 2 | name type data 3 | zil_commit_count 4 10 4 | zil_commit_writer_count 4 0 5 | zil_itx_count 4 0 6 | zil_itx_indirect_count 4 0 7 | zil_itx_indirect_bytes 4 0 8 | zil_itx_copied_count 4 0 9 | zil_itx_copied_bytes 4 0 10 | zil_itx_needcopy_count 4 0 11 | zil_itx_needcopy_bytes 4 18446744073709537686 12 | zil_itx_metaslab_normal_count 4 0 13 | zil_itx_metaslab_normal_bytes 4 0 14 | zil_itx_metaslab_slog_count 4 0 15 | zil_itx_metaslab_slog_bytes 4 0 16 | -------------------------------------------------------------------------------- /collector/fixtures/proc/stat: -------------------------------------------------------------------------------- 1 | cpu 301854 612 111922 8979004 3552 2 3944 0 44 36 2 | cpu0 44490 19 21045 1087069 220 1 3410 0 2 1 3 | cpu1 47869 23 16474 1110787 591 0 46 0 3 2 4 | cpu2 46504 36 15916 1112321 441 0 326 0 4 3 5 | cpu3 47054 102 15683 1113230 533 0 60 0 5 4 6 | cpu4 28413 25 10776 1140321 217 0 8 0 6 5 7 | cpu5 29271 101 11586 1136270 672 0 30 0 7 6 8 | cpu6 29152 36 10276 1139721 319 0 29 0 8 7 9 | cpu7 29098 268 10164 1139282 555 0 31 0 9 8 10 | intr 8885917 17 0 0 0 0 0 0 0 1 79281 0 0 0 0 0 0 0 231237 0 0 0 0 250586 103 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 223424 190745 13 906 1283803 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 | ctxt 38014093 12 | btime 1418183276 13 | processes 26442 14 | procs_running 2 15 | procs_blocked 0 16 | softirq 5057579 250191 1481983 1647 211099 186066 0 1783454 622196 12499 508444 17 | -------------------------------------------------------------------------------- /collector/fixtures/proc/sys/fs/file-nr: -------------------------------------------------------------------------------- 1 | 1024 0 1631329 2 | -------------------------------------------------------------------------------- /collector/fixtures/proc/sys/kernel/pid_max: -------------------------------------------------------------------------------- 1 | 123 2 | -------------------------------------------------------------------------------- /collector/fixtures/proc/sys/kernel/random/entropy_avail: -------------------------------------------------------------------------------- 1 | 1337 2 | -------------------------------------------------------------------------------- /collector/fixtures/proc/sys/kernel/threads-max: -------------------------------------------------------------------------------- 1 | 7801 -------------------------------------------------------------------------------- /collector/fixtures/proc/sys/net/netfilter/nf_conntrack_count: -------------------------------------------------------------------------------- 1 | 123 2 | -------------------------------------------------------------------------------- /collector/fixtures/proc/sys/net/netfilter/nf_conntrack_max: -------------------------------------------------------------------------------- 1 | 65536 2 | -------------------------------------------------------------------------------- /collector/fixtures/proc/sys/pid_max: -------------------------------------------------------------------------------- 1 | 123 2 | -------------------------------------------------------------------------------- /collector/fixtures/proc/sys/threads-max: -------------------------------------------------------------------------------- 1 | 7801 -------------------------------------------------------------------------------- /collector/fixtures/qdisc/results.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "IfaceName": "wlan0", 4 | "Bytes": 42, 5 | "Packets": 42, 6 | "Requeues": 1, 7 | "Kind": "fq", 8 | "Drops": 1 9 | }, 10 | { 11 | "IfaceName": "eth0", 12 | "Bytes": 83, 13 | "Packets": 83, 14 | "Requeues": 2, 15 | "Kind": "pfifo_fast" 16 | } 17 | ] 18 | -------------------------------------------------------------------------------- /collector/fixtures/textfile/client_side_timestamp/metrics.prom: -------------------------------------------------------------------------------- 1 | metric_with_custom_timestamp 1 1441205977284 2 | normal_metric 2 3 | -------------------------------------------------------------------------------- /collector/fixtures/textfile/different_metric_types/metrics.prom: -------------------------------------------------------------------------------- 1 | # HELP events_total this is a test metric 2 | # TYPE events_total counter 3 | events_total{foo="bar"} 10 4 | events_total{foo="baz"} 20 5 | 6 | # HELP event_duration_seconds_total Query timings 7 | # TYPE event_duration_seconds_total summary 8 | event_duration_seconds_total{baz="inner_eval",quantile="0.5"} 1.073e-06 9 | event_duration_seconds_total{baz="inner_eval",quantile="0.9"} 1.928e-06 10 | event_duration_seconds_total{baz="inner_eval",quantile="0.99"} 4.35e-06 11 | event_duration_seconds_total_sum{baz="inner_eval"} 1.8652166505091474e+06 12 | event_duration_seconds_total_count{baz="inner_eval"} 1.492355615e+09 13 | event_duration_seconds_total{baz="prepare_time",quantile="0.5"} 4.283e-06 14 | event_duration_seconds_total{baz="prepare_time",quantile="0.9"} 7.796e-06 15 | event_duration_seconds_total{baz="prepare_time",quantile="0.99"} 2.2083e-05 16 | event_duration_seconds_total_sum{baz="prepare_time"} 840923.7919437207 17 | event_duration_seconds_total_count{baz="prepare_time"} 1.492355814e+09 18 | event_duration_seconds_total{baz="result_append",quantile="0.5"} 1.566e-06 19 | event_duration_seconds_total{baz="result_append",quantile="0.9"} 3.223e-06 20 | event_duration_seconds_total{baz="result_append",quantile="0.99"} 6.53e-06 21 | event_duration_seconds_total_sum{baz="result_append"} 4.404109951000078 22 | event_duration_seconds_total_count{baz="result_append"} 1.427647e+06 23 | event_duration_seconds_total{baz="result_sort",quantile="0.5"} 1.847e-06 24 | event_duration_seconds_total{baz="result_sort",quantile="0.9"} 2.975e-06 25 | event_duration_seconds_total{baz="result_sort",quantile="0.99"} 4.08e-06 26 | event_duration_seconds_total_sum{baz="result_sort"} 3.4123187829998307 27 | event_duration_seconds_total_count{baz="result_sort"} 1.427647e+06 28 | 29 | -------------------------------------------------------------------------------- /collector/fixtures/textfile/histogram/metrics.prom: -------------------------------------------------------------------------------- 1 | # HELP prometheus_tsdb_compaction_chunk_range Final time range of chunks on their first compaction 2 | # TYPE prometheus_tsdb_compaction_chunk_range histogram 3 | prometheus_tsdb_compaction_chunk_range_bucket{le="100"} 0 4 | prometheus_tsdb_compaction_chunk_range_bucket{le="400"} 0 5 | prometheus_tsdb_compaction_chunk_range_bucket{le="1600"} 0 6 | prometheus_tsdb_compaction_chunk_range_bucket{le="6400"} 0 7 | prometheus_tsdb_compaction_chunk_range_bucket{le="25600"} 7 8 | prometheus_tsdb_compaction_chunk_range_bucket{le="102400"} 7 9 | prometheus_tsdb_compaction_chunk_range_bucket{le="409600"} 1.412839e+06 10 | prometheus_tsdb_compaction_chunk_range_bucket{le="1.6384e+06"} 1.69185e+06 11 | prometheus_tsdb_compaction_chunk_range_bucket{le="6.5536e+06"} 1.691853e+06 12 | prometheus_tsdb_compaction_chunk_range_bucket{le="2.62144e+07"} 1.691853e+06 13 | prometheus_tsdb_compaction_chunk_range_bucket{le="+Inf"} 1.691853e+06 14 | prometheus_tsdb_compaction_chunk_range_sum 6.71393432189e+11 15 | prometheus_tsdb_compaction_chunk_range_count 1.691853e+06 16 | -------------------------------------------------------------------------------- /collector/fixtures/textfile/histogram_extra_dimension/metrics.prom: -------------------------------------------------------------------------------- 1 | # HELP prometheus_tsdb_compaction_chunk_range Final time range of chunks on their first compaction 2 | # TYPE prometheus_tsdb_compaction_chunk_range histogram 3 | prometheus_tsdb_compaction_chunk_range_bucket{foo="bar",le="100"} 0 4 | prometheus_tsdb_compaction_chunk_range_bucket{foo="bar",le="400"} 0 5 | prometheus_tsdb_compaction_chunk_range_bucket{foo="bar",le="1600"} 0 6 | prometheus_tsdb_compaction_chunk_range_bucket{foo="bar",le="6400"} 0 7 | prometheus_tsdb_compaction_chunk_range_bucket{foo="bar",le="25600"} 7 8 | prometheus_tsdb_compaction_chunk_range_bucket{foo="bar",le="102400"} 7 9 | prometheus_tsdb_compaction_chunk_range_bucket{foo="bar",le="409600"} 1.412839e+06 10 | prometheus_tsdb_compaction_chunk_range_bucket{foo="bar",le="1.6384e+06"} 1.69185e+06 11 | prometheus_tsdb_compaction_chunk_range_bucket{foo="bar",le="6.5536e+06"} 1.691853e+06 12 | prometheus_tsdb_compaction_chunk_range_bucket{foo="bar",le="2.62144e+07"} 1.691853e+06 13 | prometheus_tsdb_compaction_chunk_range_bucket{foo="bar",le="+Inf"} 1.691853e+06 14 | prometheus_tsdb_compaction_chunk_range_sum{foo="bar"} 6.71393432189e+11 15 | prometheus_tsdb_compaction_chunk_range_count{foo="bar"} 1.691853e+06 16 | prometheus_tsdb_compaction_chunk_range_bucket{foo="baz",le="100"} 0 17 | prometheus_tsdb_compaction_chunk_range_bucket{foo="baz",le="400"} 0 18 | prometheus_tsdb_compaction_chunk_range_bucket{foo="baz",le="1600"} 0 19 | prometheus_tsdb_compaction_chunk_range_bucket{foo="baz",le="6400"} 0 20 | prometheus_tsdb_compaction_chunk_range_bucket{foo="baz",le="25600"} 7 21 | prometheus_tsdb_compaction_chunk_range_bucket{foo="baz",le="102400"} 7 22 | prometheus_tsdb_compaction_chunk_range_bucket{foo="baz",le="409600"} 1.412839e+06 23 | prometheus_tsdb_compaction_chunk_range_bucket{foo="baz",le="1.6384e+06"} 1.69185e+06 24 | prometheus_tsdb_compaction_chunk_range_bucket{foo="baz",le="6.5536e+06"} 1.691853e+06 25 | prometheus_tsdb_compaction_chunk_range_bucket{foo="baz",le="2.62144e+07"} 1.691853e+06 26 | prometheus_tsdb_compaction_chunk_range_bucket{foo="baz",le="+Inf"} 1.691853e+06 27 | prometheus_tsdb_compaction_chunk_range_sum{foo="baz"} 6.71393432189e+11 28 | prometheus_tsdb_compaction_chunk_range_count{foo="baz"} 1.691853e+06 29 | -------------------------------------------------------------------------------- /collector/fixtures/textfile/inconsistent_metrics/metrics.prom: -------------------------------------------------------------------------------- 1 | # HELP http_requests_total Total number of HTTP requests made. 2 | # TYPE http_requests_total counter 3 | http_requests_total{code="200",handler="alerts",method="get"} 35 4 | http_requests_total{code="200",handler="config",method="get"} 8 5 | http_requests_total{code="200",method="get", foo="bar"} 325 6 | http_requests_total{code="200",handler="flags",method="get"} 18 7 | http_requests_total{code="200",handler="graph",method="get"} 89 8 | http_requests_total{code="200",method="get", baz="bar"} 93 9 | http_requests_total{code="200",handler="prometheus",method="get"} 17051 10 | http_requests_total{code="200",handler="query",method="get"} 401 11 | http_requests_total{code="200",handler="query_range",method="get"} 15663 12 | http_requests_total{code="200",handler="rules",method="get"} 7 13 | http_requests_total{code="200",handler="series",method="get"} 221 14 | http_requests_total{code="200",handler="static",method="get"} 1647 15 | http_requests_total{code="200",handler="status",method="get"} 12 16 | http_requests_total{code="200",method="get"} 11 17 | http_requests_total{code="206",handler="static",method="get"} 2 18 | http_requests_total{code="400",handler="query_range",method="get"} 40 19 | http_requests_total{code="503",handler="query_range",method="get"} 3 20 | 21 | # HELP go_goroutines Number of goroutines that currently exist. 22 | # TYPE go_goroutines gauge 23 | go_goroutines{foo="bar"} 229 24 | go_goroutines 20 25 | -------------------------------------------------------------------------------- /collector/fixtures/textfile/no_metric_files/non_matching_file.txt: -------------------------------------------------------------------------------- 1 | This file should be ignored. 2 | -------------------------------------------------------------------------------- /collector/fixtures/textfile/summary/metrics.prom: -------------------------------------------------------------------------------- 1 | # HELP event_duration_seconds_total Query timings 2 | # TYPE event_duration_seconds_total summary 3 | event_duration_seconds_total{baz="inner_eval",quantile="0.5"} 1.073e-06 4 | event_duration_seconds_total{baz="inner_eval",quantile="0.9"} 1.928e-06 5 | event_duration_seconds_total{baz="inner_eval",quantile="0.99"} 4.35e-06 6 | event_duration_seconds_total_sum{baz="inner_eval"} 1.8652166505091474e+06 7 | event_duration_seconds_total_count{baz="inner_eval"} 1.492355615e+09 8 | event_duration_seconds_total{baz="prepare_time",quantile="0.5"} 4.283e-06 9 | event_duration_seconds_total{baz="prepare_time",quantile="0.9"} 7.796e-06 10 | event_duration_seconds_total{baz="prepare_time",quantile="0.99"} 2.2083e-05 11 | event_duration_seconds_total_sum{baz="prepare_time"} 840923.7919437207 12 | event_duration_seconds_total_count{baz="prepare_time"} 1.492355814e+09 13 | event_duration_seconds_total{baz="result_append",quantile="0.5"} 1.566e-06 14 | event_duration_seconds_total{baz="result_append",quantile="0.9"} 3.223e-06 15 | event_duration_seconds_total{baz="result_append",quantile="0.99"} 6.53e-06 16 | event_duration_seconds_total_sum{baz="result_append"} 4.404109951000078 17 | event_duration_seconds_total_count{baz="result_append"} 1.427647e+06 18 | event_duration_seconds_total{baz="result_sort",quantile="0.5"} 1.847e-06 19 | event_duration_seconds_total{baz="result_sort",quantile="0.9"} 2.975e-06 20 | event_duration_seconds_total{baz="result_sort",quantile="0.99"} 4.08e-06 21 | event_duration_seconds_total_sum{baz="result_sort"} 3.4123187829998307 22 | event_duration_seconds_total_count{baz="result_sort"} 1.427647e+06 23 | -------------------------------------------------------------------------------- /collector/fixtures/textfile/summary_extra_dimension/metrics.prom: -------------------------------------------------------------------------------- 1 | # HELP prometheus_rule_evaluation_duration_seconds The duration for a rule to execute. 2 | # TYPE prometheus_rule_evaluation_duration_seconds summary 3 | prometheus_rule_evaluation_duration_seconds{rule_type="alerting",quantile="0.5", handler="foo"} 0.000571464 4 | prometheus_rule_evaluation_duration_seconds{rule_type="alerting",quantile="0.9"} 0.001765451 5 | prometheus_rule_evaluation_duration_seconds{rule_type="alerting",quantile="0.99"} 0.018672076 6 | prometheus_rule_evaluation_duration_seconds_sum{rule_type="alerting"} 214.85081044700146 7 | prometheus_rule_evaluation_duration_seconds_count{rule_type="alerting"} 185209 8 | prometheus_rule_evaluation_duration_seconds{rule_type="recording",quantile="0.5"} 4.3132e-05 9 | prometheus_rule_evaluation_duration_seconds{rule_type="recording",quantile="0.9"} 8.9295e-05 10 | prometheus_rule_evaluation_duration_seconds{rule_type="recording",quantile="0.99"} 0.000193657 11 | prometheus_rule_evaluation_duration_seconds_sum{rule_type="recording"} 185091.01317759082 12 | prometheus_rule_evaluation_duration_seconds_count{rule_type="recording"} 1.0020195e+08 13 | -------------------------------------------------------------------------------- /collector/fixtures/textfile/two_metric_files/metrics1.prom: -------------------------------------------------------------------------------- 1 | testmetric1_1{foo="bar"} 10 2 | testmetric1_2{foo="baz"} 20 3 | -------------------------------------------------------------------------------- /collector/fixtures/textfile/two_metric_files/metrics2.prom: -------------------------------------------------------------------------------- 1 | testmetric2_1{foo="bar"} 30 2 | testmetric2_2{foo="baz"} 40 3 | -------------------------------------------------------------------------------- /collector/fixtures/textfile/two_metric_files/non_matching_file.txt: -------------------------------------------------------------------------------- 1 | This file should be ignored. 2 | -------------------------------------------------------------------------------- /collector/fixtures/wifi/interfaces.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "wlan0", 4 | "type": 2, 5 | "frequency": 2412 6 | }, 7 | { 8 | "name": "wlan1", 9 | "type": 3, 10 | "frequency": 2412 11 | }, 12 | { 13 | "type": 10 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /collector/fixtures/wifi/wlan0/bss.json: -------------------------------------------------------------------------------- 1 | { 2 | "ssid": "Example", 3 | "bssid": "ABEiM0RV", 4 | "status": 1 5 | } 6 | -------------------------------------------------------------------------------- /collector/fixtures/wifi/wlan0/stationinfo.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "hardwareaddr": "qrvM3e7/", 4 | "connected": 30000000000, 5 | "inactive": 400000000, 6 | "receivebitrate": 128000000, 7 | "transmitbitrate": 164000000, 8 | "signal": -52, 9 | "transmitretries": 10, 10 | "transmitfailed": 2, 11 | "beaconloss": 1 12 | }, 13 | { 14 | "hardwareaddr": "AQIDBAUG", 15 | "connected": 60000000000, 16 | "inactive": 800000000, 17 | "receivebitrate": 256000000, 18 | "transmitbitrate": 328000000, 19 | "signal": -26, 20 | "transmitretries": 20, 21 | "transmitfailed": 4, 22 | "beaconloss": 2 23 | } 24 | ] 25 | 26 | -------------------------------------------------------------------------------- /collector/fixtures_bindmount/proc/mounts: -------------------------------------------------------------------------------- 1 | /dev/nvme1n0 /host ext4 rw,seclabel,relatime,data=ordered 0 0 2 | /dev/nvme1n1 /host/media/volume1 ext4 rw,seclabel,relatime,data=ordered 0 0 3 | /dev/nvme1n2 /host/media/volume2 ext4 rw,seclabel,relatime,data=ordered 0 0 4 | tmpfs /dev/shm tmpfs rw,nosuid,nodev 0 0 5 | tmpfs /run/lock tmpfs rw,nosuid,nodev,noexec,relatime,size=5120k 0 0 6 | tmpfs /sys/fs/cgroup tmpfs ro,nosuid,nodev,noexec,mode=755 0 0 7 | -------------------------------------------------------------------------------- /collector/fixtures_hidepid/proc/mounts: -------------------------------------------------------------------------------- 1 | rootfs / rootfs rw 0 0 2 | -------------------------------------------------------------------------------- /collector/helper.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package collector 15 | 16 | import ( 17 | "bytes" 18 | "io/ioutil" 19 | "strconv" 20 | "strings" 21 | ) 22 | 23 | func readUintFromFile(path string) (uint64, error) { 24 | data, err := ioutil.ReadFile(path) 25 | if err != nil { 26 | return 0, err 27 | } 28 | value, err := strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64) 29 | if err != nil { 30 | return 0, err 31 | } 32 | return value, nil 33 | } 34 | 35 | // Take a []byte{} and return a string based on null termination. 36 | // This is useful for situations where the OS has returned a null terminated 37 | // string to use. 38 | // If this function happens to receive a byteArray that contains no nulls, we 39 | // simply convert the array to a string with no bounding. 40 | func bytesToString(byteArray []byte) string { 41 | n := bytes.IndexByte(byteArray, 0) 42 | if n < 0 { 43 | return string(byteArray) 44 | } 45 | return string(byteArray[:n]) 46 | } 47 | -------------------------------------------------------------------------------- /collector/helper_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package collector 15 | 16 | import ( 17 | "testing" 18 | ) 19 | 20 | func TestBytesToString(t *testing.T) { 21 | tests := []struct { 22 | name string 23 | b []byte 24 | expected string 25 | }{ 26 | { 27 | "Single null byte", 28 | []byte{0}, 29 | "", 30 | }, 31 | { 32 | "Empty byte array", 33 | []byte{}, 34 | "", 35 | }, 36 | { 37 | "Not null terminated", 38 | []byte{65, 66, 67}, 39 | "ABC", 40 | }, 41 | { 42 | "Null randomly in array", 43 | []byte{65, 66, 67, 0, 65, 0, 65}, 44 | "ABC", 45 | }, 46 | { 47 | "Array starts with null and contains other valid bytes", 48 | []byte{0, 65, 66, 67, 0}, 49 | "", 50 | }, 51 | } 52 | 53 | for _, tt := range tests { 54 | name := tt.name 55 | b := tt.b 56 | result := bytesToString(b) 57 | expected := tt.expected 58 | 59 | if result != expected { 60 | t.Errorf("bytesToString(%#v): Name: %s, expected %#v, got %#v)", b, name, expected, result) 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /collector/interrupts_common.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build linux openbsd 15 | // +build !nointerrupts 16 | 17 | package collector 18 | 19 | import ( 20 | "github.com/go-kit/kit/log" 21 | "github.com/prometheus/client_golang/prometheus" 22 | ) 23 | 24 | type interruptsCollector struct { 25 | desc typedDesc 26 | logger log.Logger 27 | } 28 | 29 | func init() { 30 | registerCollector("interrupts", defaultDisabled, NewInterruptsCollector) 31 | } 32 | 33 | // NewInterruptsCollector returns a new Collector exposing interrupts stats. 34 | func NewInterruptsCollector(logger log.Logger) (Collector, error) { 35 | return &interruptsCollector{ 36 | desc: typedDesc{prometheus.NewDesc( 37 | namespace+"_interrupts_total", 38 | "Interrupt details.", 39 | interruptLabelNames, nil, 40 | ), prometheus.CounterValue}, 41 | logger: logger, 42 | }, nil 43 | } 44 | -------------------------------------------------------------------------------- /collector/interrupts_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !nointerrupts 15 | 16 | package collector 17 | 18 | import ( 19 | "bufio" 20 | "errors" 21 | "fmt" 22 | "io" 23 | "os" 24 | "strconv" 25 | "strings" 26 | 27 | "github.com/prometheus/client_golang/prometheus" 28 | ) 29 | 30 | var ( 31 | interruptLabelNames = []string{"cpu", "type", "info", "devices"} 32 | ) 33 | 34 | func (c *interruptsCollector) Update(ch chan<- prometheus.Metric) (err error) { 35 | interrupts, err := getInterrupts() 36 | if err != nil { 37 | return fmt.Errorf("couldn't get interrupts: %w", err) 38 | } 39 | for name, interrupt := range interrupts { 40 | for cpuNo, value := range interrupt.values { 41 | fv, err := strconv.ParseFloat(value, 64) 42 | if err != nil { 43 | return fmt.Errorf("invalid value %s in interrupts: %w", value, err) 44 | } 45 | ch <- c.desc.mustNewConstMetric(fv, strconv.Itoa(cpuNo), name, interrupt.info, interrupt.devices) 46 | } 47 | } 48 | return err 49 | } 50 | 51 | type interrupt struct { 52 | info string 53 | devices string 54 | values []string 55 | } 56 | 57 | func getInterrupts() (map[string]interrupt, error) { 58 | file, err := os.Open(procFilePath("interrupts")) 59 | if err != nil { 60 | return nil, err 61 | } 62 | defer file.Close() 63 | 64 | return parseInterrupts(file) 65 | } 66 | 67 | func parseInterrupts(r io.Reader) (map[string]interrupt, error) { 68 | var ( 69 | interrupts = map[string]interrupt{} 70 | scanner = bufio.NewScanner(r) 71 | ) 72 | 73 | if !scanner.Scan() { 74 | return nil, errors.New("interrupts empty") 75 | } 76 | cpuNum := len(strings.Fields(scanner.Text())) // one header per cpu 77 | 78 | for scanner.Scan() { 79 | parts := strings.Fields(scanner.Text()) 80 | if len(parts) < cpuNum+2 { // irq + one column per cpu + details, 81 | continue // we ignore ERR and MIS for now 82 | } 83 | intName := parts[0][:len(parts[0])-1] // remove trailing : 84 | intr := interrupt{ 85 | values: parts[1 : cpuNum+1], 86 | } 87 | 88 | if _, err := strconv.Atoi(intName); err == nil { // numeral interrupt 89 | intr.info = parts[cpuNum+1] 90 | intr.devices = strings.Join(parts[cpuNum+2:], " ") 91 | } else { 92 | intr.info = strings.Join(parts[cpuNum+1:], " ") 93 | } 94 | interrupts[intName] = intr 95 | } 96 | 97 | return interrupts, scanner.Err() 98 | } 99 | -------------------------------------------------------------------------------- /collector/interrupts_linux_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package collector 15 | 16 | import ( 17 | "os" 18 | "testing" 19 | ) 20 | 21 | func TestInterrupts(t *testing.T) { 22 | file, err := os.Open("fixtures/proc/interrupts") 23 | if err != nil { 24 | t.Fatal(err) 25 | } 26 | defer file.Close() 27 | 28 | interrupts, err := parseInterrupts(file) 29 | if err != nil { 30 | t.Fatal(err) 31 | } 32 | 33 | if want, got := "5031", interrupts["NMI"].values[1]; want != got { 34 | t.Errorf("want interrupts %s, got %s", want, got) 35 | } 36 | 37 | if want, got := "4968", interrupts["NMI"].values[3]; want != got { 38 | t.Errorf("want interrupts %s, got %s", want, got) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /collector/ksmd_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !noksmd 15 | 16 | package collector 17 | 18 | import ( 19 | "fmt" 20 | "path/filepath" 21 | 22 | "github.com/go-kit/kit/log" 23 | "github.com/prometheus/client_golang/prometheus" 24 | ) 25 | 26 | var ( 27 | ksmdFiles = []string{"full_scans", "merge_across_nodes", "pages_shared", "pages_sharing", 28 | "pages_to_scan", "pages_unshared", "pages_volatile", "run", "sleep_millisecs"} 29 | ) 30 | 31 | type ksmdCollector struct { 32 | metricDescs map[string]*prometheus.Desc 33 | logger log.Logger 34 | } 35 | 36 | func init() { 37 | registerCollector("ksmd", defaultDisabled, NewKsmdCollector) 38 | } 39 | 40 | func getCanonicalMetricName(filename string) string { 41 | switch filename { 42 | case "full_scans": 43 | return filename + "_total" 44 | case "sleep_millisecs": 45 | return "sleep_seconds" 46 | default: 47 | return filename 48 | } 49 | } 50 | 51 | // NewKsmdCollector returns a new Collector exposing kernel/system statistics. 52 | func NewKsmdCollector(logger log.Logger) (Collector, error) { 53 | subsystem := "ksmd" 54 | descs := make(map[string]*prometheus.Desc) 55 | 56 | for _, n := range ksmdFiles { 57 | descs[n] = prometheus.NewDesc( 58 | prometheus.BuildFQName(namespace, subsystem, getCanonicalMetricName(n)), 59 | fmt.Sprintf("ksmd '%s' file.", n), nil, nil) 60 | } 61 | return &ksmdCollector{descs, logger}, nil 62 | } 63 | 64 | // Update implements Collector and exposes kernel and system statistics. 65 | func (c *ksmdCollector) Update(ch chan<- prometheus.Metric) error { 66 | for _, n := range ksmdFiles { 67 | val, err := readUintFromFile(sysFilePath(filepath.Join("kernel/mm/ksm", n))) 68 | if err != nil { 69 | return err 70 | } 71 | 72 | t := prometheus.GaugeValue 73 | v := float64(val) 74 | switch n { 75 | case "full_scans": 76 | t = prometheus.CounterValue 77 | case "sleep_millisecs": 78 | v /= 1000 79 | } 80 | ch <- prometheus.MustNewConstMetric(c.metricDescs[n], t, v) 81 | } 82 | 83 | return nil 84 | } 85 | -------------------------------------------------------------------------------- /collector/kvm_bsd.c: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !nomeminfo 15 | // +build freebsd dragonfly 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | int _kvm_swap_used_pages(uint64_t *out) { 24 | const int total_only = 1; // from kvm_getswapinfo(3) 25 | 26 | kvm_t *kd; 27 | struct kvm_swap current; 28 | 29 | kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, NULL); 30 | if (kd == NULL) { 31 | return -1; 32 | } 33 | 34 | if (kvm_getswapinfo(kd, ¤t, total_only, 0) == -1) { 35 | goto error1; 36 | } 37 | 38 | if (kvm_close(kd) != 0) { 39 | return -1; 40 | } 41 | kd = NULL; 42 | 43 | *out = current.ksw_used; 44 | return 0; 45 | 46 | error1: 47 | if (kd != NULL) { 48 | kvm_close(kd); 49 | } 50 | 51 | return -1; 52 | } 53 | -------------------------------------------------------------------------------- /collector/kvm_bsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !nokvm 15 | // +build freebsd dragonfly 16 | 17 | package collector 18 | 19 | import ( 20 | "fmt" 21 | "sync" 22 | ) 23 | 24 | // #cgo LDFLAGS: -lkvm 25 | // #include "kvm_bsd.h" 26 | import "C" 27 | 28 | type kvm struct { 29 | mu sync.Mutex 30 | hasErr bool 31 | } 32 | 33 | func (k *kvm) SwapUsedPages() (value uint64, err error) { 34 | k.mu.Lock() 35 | defer k.mu.Unlock() 36 | if C._kvm_swap_used_pages((*C.uint64_t)(&value)) == -1 { 37 | k.hasErr = true 38 | return 0, fmt.Errorf("couldn't get kvm stats") 39 | } 40 | 41 | return value, nil 42 | } 43 | -------------------------------------------------------------------------------- /collector/kvm_bsd.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !nomeminfo 15 | // +build freebsd dragonfly 16 | 17 | #include 18 | 19 | int _kvm_swap_used_pages(uint64_t *out); 20 | -------------------------------------------------------------------------------- /collector/loadavg.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build darwin dragonfly freebsd linux netbsd openbsd solaris 15 | // +build !noloadavg 16 | 17 | package collector 18 | 19 | import ( 20 | "fmt" 21 | 22 | "github.com/go-kit/kit/log" 23 | "github.com/go-kit/kit/log/level" 24 | "github.com/prometheus/client_golang/prometheus" 25 | ) 26 | 27 | type loadavgCollector struct { 28 | metric []typedDesc 29 | logger log.Logger 30 | } 31 | 32 | func init() { 33 | registerCollector("loadavg", defaultEnabled, NewLoadavgCollector) 34 | } 35 | 36 | // NewLoadavgCollector returns a new Collector exposing load average stats. 37 | func NewLoadavgCollector(logger log.Logger) (Collector, error) { 38 | return &loadavgCollector{ 39 | metric: []typedDesc{ 40 | {prometheus.NewDesc(namespace+"_load1", "1m load average.", nil, nil), prometheus.GaugeValue}, 41 | {prometheus.NewDesc(namespace+"_load5", "5m load average.", nil, nil), prometheus.GaugeValue}, 42 | {prometheus.NewDesc(namespace+"_load15", "15m load average.", nil, nil), prometheus.GaugeValue}, 43 | }, 44 | logger: logger, 45 | }, nil 46 | } 47 | 48 | func (c *loadavgCollector) Update(ch chan<- prometheus.Metric) error { 49 | loads, err := getLoad() 50 | if err != nil { 51 | return fmt.Errorf("couldn't get load: %w", err) 52 | } 53 | for i, load := range loads { 54 | level.Debug(c.logger).Log("msg", "return load", "index", i, "load", load) 55 | ch <- c.metric[i].mustNewConstMetric(load) 56 | } 57 | return err 58 | } 59 | -------------------------------------------------------------------------------- /collector/loadavg_bsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build darwin dragonfly freebsd netbsd openbsd 15 | // +build !noloadavg 16 | 17 | package collector 18 | 19 | import ( 20 | "unsafe" 21 | 22 | "golang.org/x/sys/unix" 23 | ) 24 | 25 | func getLoad() ([]float64, error) { 26 | type loadavg struct { 27 | load [3]uint32 28 | scale int 29 | } 30 | b, err := unix.SysctlRaw("vm.loadavg") 31 | if err != nil { 32 | return nil, err 33 | } 34 | load := *(*loadavg)(unsafe.Pointer((&b[0]))) 35 | scale := float64(load.scale) 36 | return []float64{ 37 | float64(load.load[0]) / scale, 38 | float64(load.load[1]) / scale, 39 | float64(load.load[2]) / scale, 40 | }, nil 41 | } 42 | -------------------------------------------------------------------------------- /collector/loadavg_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !noloadavg 15 | 16 | package collector 17 | 18 | import ( 19 | "fmt" 20 | "io/ioutil" 21 | "strconv" 22 | "strings" 23 | ) 24 | 25 | // Read loadavg from /proc. 26 | func getLoad() (loads []float64, err error) { 27 | data, err := ioutil.ReadFile(procFilePath("loadavg")) 28 | if err != nil { 29 | return nil, err 30 | } 31 | loads, err = parseLoad(string(data)) 32 | if err != nil { 33 | return nil, err 34 | } 35 | return loads, nil 36 | } 37 | 38 | // Parse /proc loadavg and return 1m, 5m and 15m. 39 | func parseLoad(data string) (loads []float64, err error) { 40 | loads = make([]float64, 3) 41 | parts := strings.Fields(data) 42 | if len(parts) < 3 { 43 | return nil, fmt.Errorf("unexpected content in %s", procFilePath("loadavg")) 44 | } 45 | for i, load := range parts[0:3] { 46 | loads[i], err = strconv.ParseFloat(load, 64) 47 | if err != nil { 48 | return nil, fmt.Errorf("could not parse load '%s': %w", load, err) 49 | } 50 | } 51 | return loads, nil 52 | } 53 | -------------------------------------------------------------------------------- /collector/loadavg_linux_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package collector 15 | 16 | import "testing" 17 | 18 | func TestLoad(t *testing.T) { 19 | want := []float64{0.21, 0.37, 0.39} 20 | loads, err := parseLoad("0.21 0.37 0.39 1/719 19737") 21 | if err != nil { 22 | t.Fatal(err) 23 | } 24 | 25 | for i, load := range loads { 26 | if want[i] != load { 27 | t.Fatalf("want load %f, got %f", want[i], load) 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /collector/loadavg_solaris.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !noloadavg 15 | 16 | package collector 17 | 18 | import ( 19 | "fmt" 20 | "strconv" 21 | 22 | "github.com/siebenmann/go-kstat" 23 | ) 24 | 25 | // #include 26 | import "C" 27 | 28 | func kstatToFloat(ks *kstat.KStat, kstatKey string) float64 { 29 | kstatValue, err := ks.GetNamed(kstatKey) 30 | 31 | if err != nil { 32 | panic(err) 33 | } 34 | 35 | kstatLoadavg, err := strconv.ParseFloat( 36 | fmt.Sprintf("%.2f", float64(kstatValue.UintVal)/C.FSCALE), 64) 37 | 38 | if err != nil { 39 | panic(err) 40 | } 41 | 42 | return kstatLoadavg 43 | } 44 | 45 | func getLoad() ([]float64, error) { 46 | tok, err := kstat.Open() 47 | if err != nil { 48 | panic(err) 49 | } 50 | 51 | defer tok.Close() 52 | 53 | ks, err := tok.Lookup("unix", 0, "system_misc") 54 | 55 | if err != nil { 56 | panic(err) 57 | } 58 | 59 | loadavg1Min := kstatToFloat(ks, "avenrun_1min") 60 | loadavg5Min := kstatToFloat(ks, "avenrun_5min") 61 | loadavg15Min := kstatToFloat(ks, "avenrun_15min") 62 | 63 | return []float64{loadavg1Min, loadavg5Min, loadavg15Min}, nil 64 | } 65 | -------------------------------------------------------------------------------- /collector/meminfo.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build darwin linux openbsd 15 | // +build !nomeminfo 16 | 17 | package collector 18 | 19 | import ( 20 | "fmt" 21 | "strings" 22 | 23 | "github.com/go-kit/kit/log" 24 | "github.com/go-kit/kit/log/level" 25 | "github.com/prometheus/client_golang/prometheus" 26 | ) 27 | 28 | const ( 29 | memInfoSubsystem = "memory" 30 | ) 31 | 32 | type meminfoCollector struct { 33 | logger log.Logger 34 | } 35 | 36 | func init() { 37 | registerCollector("meminfo", defaultEnabled, NewMeminfoCollector) 38 | } 39 | 40 | // NewMeminfoCollector returns a new Collector exposing memory stats. 41 | func NewMeminfoCollector(logger log.Logger) (Collector, error) { 42 | return &meminfoCollector{logger}, nil 43 | } 44 | 45 | // Update calls (*meminfoCollector).getMemInfo to get the platform specific 46 | // memory metrics. 47 | func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) error { 48 | var metricType prometheus.ValueType 49 | memInfo, err := c.getMemInfo() 50 | if err != nil { 51 | return fmt.Errorf("couldn't get meminfo: %w", err) 52 | } 53 | level.Debug(c.logger).Log("msg", "Set node_mem", "memInfo", memInfo) 54 | for k, v := range memInfo { 55 | if strings.HasSuffix(k, "_total") { 56 | metricType = prometheus.CounterValue 57 | } else { 58 | metricType = prometheus.GaugeValue 59 | } 60 | ch <- prometheus.MustNewConstMetric( 61 | prometheus.NewDesc( 62 | prometheus.BuildFQName(namespace, memInfoSubsystem, k), 63 | fmt.Sprintf("Memory information field %s.", k), 64 | nil, nil, 65 | ), 66 | metricType, v, 67 | ) 68 | } 69 | return nil 70 | } 71 | -------------------------------------------------------------------------------- /collector/meminfo_darwin.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !nomeminfo 15 | 16 | package collector 17 | 18 | // #include 19 | // #include 20 | // typedef struct xsw_usage xsw_usage_t; 21 | import "C" 22 | 23 | import ( 24 | "encoding/binary" 25 | "fmt" 26 | "unsafe" 27 | 28 | "golang.org/x/sys/unix" 29 | ) 30 | 31 | func (c *meminfoCollector) getMemInfo() (map[string]float64, error) { 32 | host := C.mach_host_self() 33 | infoCount := C.mach_msg_type_number_t(C.HOST_VM_INFO64_COUNT) 34 | vmstat := C.vm_statistics64_data_t{} 35 | ret := C.host_statistics64( 36 | C.host_t(host), 37 | C.HOST_VM_INFO64, 38 | C.host_info_t(unsafe.Pointer(&vmstat)), 39 | &infoCount, 40 | ) 41 | if ret != C.KERN_SUCCESS { 42 | return nil, fmt.Errorf("Couldn't get memory statistics, host_statistics returned %d", ret) 43 | } 44 | totalb, err := unix.Sysctl("hw.memsize") 45 | if err != nil { 46 | return nil, err 47 | } 48 | 49 | swapraw, err := unix.SysctlRaw("vm.swapusage") 50 | if err != nil { 51 | return nil, err 52 | } 53 | swap := (*C.xsw_usage_t)(unsafe.Pointer(&swapraw[0])) 54 | 55 | // Syscall removes terminating NUL which we need to cast to uint64 56 | total := binary.LittleEndian.Uint64([]byte(totalb + "\x00")) 57 | 58 | var pageSize C.vm_size_t 59 | C.host_page_size(C.host_t(host), &pageSize) 60 | 61 | ps := float64(pageSize) 62 | return map[string]float64{ 63 | "active_bytes": ps * float64(vmstat.active_count), 64 | "compressed_bytes": ps * float64(vmstat.compressor_page_count), 65 | "inactive_bytes": ps * float64(vmstat.inactive_count), 66 | "wired_bytes": ps * float64(vmstat.wire_count), 67 | "free_bytes": ps * float64(vmstat.free_count), 68 | "swapped_in_bytes_total": ps * float64(vmstat.pageins), 69 | "swapped_out_bytes_total": ps * float64(vmstat.pageouts), 70 | "total_bytes": float64(total), 71 | "swap_used_bytes": float64(swap.xsu_used), 72 | "swap_total_bytes": float64(swap.xsu_total), 73 | }, nil 74 | } 75 | -------------------------------------------------------------------------------- /collector/meminfo_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !nomeminfo 15 | 16 | package collector 17 | 18 | import ( 19 | "bufio" 20 | "fmt" 21 | "io" 22 | "os" 23 | "regexp" 24 | "strconv" 25 | "strings" 26 | ) 27 | 28 | var ( 29 | reParens = regexp.MustCompile(`\((.*)\)`) 30 | ) 31 | 32 | func (c *meminfoCollector) getMemInfo() (map[string]float64, error) { 33 | file, err := os.Open(procFilePath("meminfo")) 34 | if err != nil { 35 | return nil, err 36 | } 37 | defer file.Close() 38 | 39 | return parseMemInfo(file) 40 | } 41 | 42 | func parseMemInfo(r io.Reader) (map[string]float64, error) { 43 | var ( 44 | memInfo = map[string]float64{} 45 | scanner = bufio.NewScanner(r) 46 | ) 47 | 48 | for scanner.Scan() { 49 | line := scanner.Text() 50 | parts := strings.Fields(line) 51 | // Workaround for empty lines occasionally occur in CentOS 6.2 kernel 3.10.90. 52 | if len(parts) == 0 { 53 | continue 54 | } 55 | fv, err := strconv.ParseFloat(parts[1], 64) 56 | if err != nil { 57 | return nil, fmt.Errorf("invalid value in meminfo: %w", err) 58 | } 59 | key := parts[0][:len(parts[0])-1] // remove trailing : from key 60 | // Active(anon) -> Active_anon 61 | key = reParens.ReplaceAllString(key, "_${1}") 62 | switch len(parts) { 63 | case 2: // no unit 64 | case 3: // has unit, we presume kB 65 | fv *= 1024 66 | key = key + "_bytes" 67 | default: 68 | return nil, fmt.Errorf("invalid line in meminfo: %s", line) 69 | } 70 | memInfo[key] = fv 71 | } 72 | 73 | return memInfo, scanner.Err() 74 | } 75 | -------------------------------------------------------------------------------- /collector/meminfo_linux_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package collector 15 | 16 | import ( 17 | "os" 18 | "testing" 19 | ) 20 | 21 | func TestMemInfo(t *testing.T) { 22 | file, err := os.Open("fixtures/proc/meminfo") 23 | if err != nil { 24 | t.Fatal(err) 25 | } 26 | defer file.Close() 27 | 28 | memInfo, err := parseMemInfo(file) 29 | if err != nil { 30 | t.Fatal(err) 31 | } 32 | 33 | if want, got := 3831959552.0, memInfo["MemTotal_bytes"]; want != got { 34 | t.Errorf("want memory total %f, got %f", want, got) 35 | } 36 | 37 | if want, got := 3787456512.0, memInfo["DirectMap2M_bytes"]; want != got { 38 | t.Errorf("want memory directMap2M %f, got %f", want, got) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /collector/meminfo_openbsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build openbsd 15 | // +build !nomeminfo 16 | 17 | package collector 18 | 19 | import ( 20 | "fmt" 21 | ) 22 | 23 | /* 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | int 30 | sysctl_uvmexp(struct uvmexp *uvmexp) 31 | { 32 | static int uvmexp_mib[] = {CTL_VM, VM_UVMEXP}; 33 | size_t sz = sizeof(struct uvmexp); 34 | 35 | if(sysctl(uvmexp_mib, 2, uvmexp, &sz, NULL, 0) < 0) 36 | return -1; 37 | 38 | return 0; 39 | } 40 | 41 | int 42 | sysctl_bcstats(struct bcachestats *bcstats) 43 | { 44 | static int bcstats_mib[] = {CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT}; 45 | size_t sz = sizeof(struct bcachestats); 46 | 47 | if(sysctl(bcstats_mib, 3, bcstats, &sz, NULL, 0) < 0) 48 | return -1; 49 | 50 | return 0; 51 | } 52 | 53 | */ 54 | import "C" 55 | 56 | func (c *meminfoCollector) getMemInfo() (map[string]float64, error) { 57 | var uvmexp C.struct_uvmexp 58 | var bcstats C.struct_bcachestats 59 | 60 | if _, err := C.sysctl_uvmexp(&uvmexp); err != nil { 61 | return nil, fmt.Errorf("sysctl CTL_VM VM_UVMEXP failed: %w", err) 62 | } 63 | 64 | if _, err := C.sysctl_bcstats(&bcstats); err != nil { 65 | return nil, fmt.Errorf("sysctl CTL_VFS VFS_GENERIC VFS_BCACHESTAT failed: %w", err) 66 | } 67 | 68 | ps := float64(uvmexp.pagesize) 69 | 70 | // see uvm(9) 71 | return map[string]float64{ 72 | "active_bytes": ps * float64(uvmexp.active), 73 | "cache_bytes": ps * float64(bcstats.numbufpages), 74 | "free_bytes": ps * float64(uvmexp.free), 75 | "inactive_bytes": ps * float64(uvmexp.inactive), 76 | "size_bytes": ps * float64(uvmexp.npages), 77 | "swap_size_bytes": ps * float64(uvmexp.swpages), 78 | "swap_used_bytes": ps * float64(uvmexp.swpginuse), 79 | "swapped_in_pages_bytes_total": ps * float64(uvmexp.pgswapin), 80 | "swapped_out_pages_bytes_total": ps * float64(uvmexp.pgswapout), 81 | "wired_bytes": ps * float64(uvmexp.wired), 82 | }, nil 83 | } 84 | -------------------------------------------------------------------------------- /collector/netdev_bsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !nonetdev 15 | // +build freebsd dragonfly 16 | 17 | package collector 18 | 19 | import ( 20 | "errors" 21 | "regexp" 22 | "strconv" 23 | 24 | "github.com/go-kit/kit/log" 25 | "github.com/go-kit/kit/log/level" 26 | ) 27 | 28 | /* 29 | #cgo CFLAGS: -D_IFI_OQDROPS 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | */ 36 | import "C" 37 | 38 | func getNetDevStats(ignore *regexp.Regexp, accept *regexp.Regexp, logger log.Logger) (map[string]map[string]string, error) { 39 | netDev := map[string]map[string]string{} 40 | 41 | var ifap, ifa *C.struct_ifaddrs 42 | if C.getifaddrs(&ifap) == -1 { 43 | return nil, errors.New("getifaddrs() failed") 44 | } 45 | defer C.freeifaddrs(ifap) 46 | 47 | for ifa = ifap; ifa != nil; ifa = ifa.ifa_next { 48 | if ifa.ifa_addr.sa_family == C.AF_LINK { 49 | dev := C.GoString(ifa.ifa_name) 50 | if ignore != nil && ignore.MatchString(dev) { 51 | level.Debug(logger).Log("msg", "Ignoring device", "device", dev) 52 | continue 53 | } 54 | if accept != nil && !accept.MatchString(dev) { 55 | level.Debug(logger).Log("msg", "Ignoring device", "device", dev) 56 | continue 57 | } 58 | 59 | devStats := map[string]string{} 60 | data := (*C.struct_if_data)(ifa.ifa_data) 61 | 62 | devStats["receive_packets"] = convertFreeBSDCPUTime(uint64(data.ifi_ipackets)) 63 | devStats["transmit_packets"] = convertFreeBSDCPUTime(uint64(data.ifi_opackets)) 64 | devStats["receive_errs"] = convertFreeBSDCPUTime(uint64(data.ifi_ierrors)) 65 | devStats["transmit_errs"] = convertFreeBSDCPUTime(uint64(data.ifi_oerrors)) 66 | devStats["receive_bytes"] = convertFreeBSDCPUTime(uint64(data.ifi_ibytes)) 67 | devStats["transmit_bytes"] = convertFreeBSDCPUTime(uint64(data.ifi_obytes)) 68 | devStats["receive_multicast"] = convertFreeBSDCPUTime(uint64(data.ifi_imcasts)) 69 | devStats["transmit_multicast"] = convertFreeBSDCPUTime(uint64(data.ifi_omcasts)) 70 | devStats["receive_drop"] = convertFreeBSDCPUTime(uint64(data.ifi_iqdrops)) 71 | devStats["transmit_drop"] = convertFreeBSDCPUTime(uint64(data.ifi_oqdrops)) 72 | netDev[dev] = devStats 73 | } 74 | } 75 | 76 | return netDev, nil 77 | } 78 | 79 | func convertFreeBSDCPUTime(counter uint64) string { 80 | return strconv.FormatUint(counter, 10) 81 | } 82 | -------------------------------------------------------------------------------- /collector/netdev_bsd_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !nonetdev 15 | // +build freebsd dragonfly 16 | 17 | package collector 18 | 19 | import "testing" 20 | 21 | type uintToStringTest struct { 22 | in uint64 23 | out string 24 | } 25 | 26 | var uinttostringtests = []uintToStringTest{ 27 | // Copied base10 values from strconv's tests: 28 | {0, "0"}, 29 | {1, "1"}, 30 | {12345678, "12345678"}, 31 | {1<<31 - 1, "2147483647"}, 32 | {1 << 31, "2147483648"}, 33 | {1<<31 + 1, "2147483649"}, 34 | {1<<32 - 1, "4294967295"}, 35 | {1 << 32, "4294967296"}, 36 | {1<<32 + 1, "4294967297"}, 37 | {1 << 50, "1125899906842624"}, 38 | {1<<63 - 1, "9223372036854775807"}, 39 | 40 | // Some values that convert correctly on amd64, but not on i386. 41 | {0x1bf0c640a, "7500227594"}, 42 | {0xbee5df75, "3202735989"}, 43 | } 44 | 45 | func TestUintToString(t *testing.T) { 46 | for _, test := range uinttostringtests { 47 | is := convertFreeBSDCPUTime(test.in) 48 | if is != test.out { 49 | t.Errorf("convertFreeBSDCPUTime(%v) = %v want %v", 50 | test.in, is, test.out) 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /collector/netdev_linux_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package collector 15 | 16 | import ( 17 | "github.com/go-kit/kit/log" 18 | "os" 19 | "regexp" 20 | "testing" 21 | ) 22 | 23 | func TestNetDevStatsIgnore(t *testing.T) { 24 | file, err := os.Open("fixtures/proc/net/dev") 25 | if err != nil { 26 | t.Fatal(err) 27 | } 28 | defer file.Close() 29 | 30 | netStats, err := parseNetDevStats(file, regexp.MustCompile("^veth"), nil, log.NewNopLogger()) 31 | if err != nil { 32 | t.Fatal(err) 33 | } 34 | 35 | if want, got := "10437182923", netStats["wlan0"]["receive_bytes"]; want != got { 36 | t.Errorf("want netstat wlan0 bytes %s, got %s", want, got) 37 | } 38 | 39 | if want, got := "68210035552", netStats["eth0"]["receive_bytes"]; want != got { 40 | t.Errorf("want netstat eth0 bytes %s, got %s", want, got) 41 | } 42 | 43 | if want, got := "934", netStats["tun0"]["transmit_packets"]; want != got { 44 | t.Errorf("want netstat tun0 packets %s, got %s", want, got) 45 | } 46 | 47 | if want, got := 9, len(netStats); want != got { 48 | t.Errorf("want count of devices to be %d, got %d", want, got) 49 | } 50 | 51 | if _, ok := netStats["veth4B09XN"]["transmit_bytes"]; ok { 52 | t.Error("want fixture interface veth4B09XN to not exist, but it does") 53 | } 54 | 55 | if want, got := "0", netStats["ibr10:30"]["receive_fifo"]; want != got { 56 | t.Error("want fixture interface ibr10:30 to exist, but it does not") 57 | } 58 | 59 | if want, got := "72", netStats["💩0"]["receive_multicast"]; want != got { 60 | t.Error("want fixture interface 💩0 to exist, but it does not") 61 | } 62 | } 63 | 64 | func TestNetDevStatsAccept(t *testing.T) { 65 | file, err := os.Open("fixtures/proc/net/dev") 66 | if err != nil { 67 | t.Fatal(err) 68 | } 69 | defer file.Close() 70 | 71 | netStats, err := parseNetDevStats(file, nil, regexp.MustCompile("^💩0$"), log.NewNopLogger()) 72 | if err != nil { 73 | t.Fatal(err) 74 | } 75 | 76 | if want, got := 1, len(netStats); want != got { 77 | t.Errorf("want count of devices to be %d, got %d", want, got) 78 | } 79 | if want, got := "72", netStats["💩0"]["receive_multicast"]; want != got { 80 | t.Error("want fixture interface 💩0 to exist, but it does not") 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /collector/netdev_openbsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !nonetdev 15 | 16 | package collector 17 | 18 | import ( 19 | "errors" 20 | "regexp" 21 | "strconv" 22 | 23 | "github.com/go-kit/kit/log" 24 | "github.com/go-kit/kit/log/level" 25 | ) 26 | 27 | /* 28 | #include 29 | #include 30 | #include 31 | #include 32 | */ 33 | import "C" 34 | 35 | func getNetDevStats(ignore *regexp.Regexp, accept *regexp.Regexp, logger log.Logger) (map[string]map[string]string, error) { 36 | netDev := map[string]map[string]string{} 37 | 38 | var ifap, ifa *C.struct_ifaddrs 39 | if C.getifaddrs(&ifap) == -1 { 40 | return nil, errors.New("getifaddrs() failed") 41 | } 42 | defer C.freeifaddrs(ifap) 43 | 44 | for ifa = ifap; ifa != nil; ifa = ifa.ifa_next { 45 | if ifa.ifa_addr.sa_family == C.AF_LINK { 46 | dev := C.GoString(ifa.ifa_name) 47 | if ignore != nil && ignore.MatchString(dev) { 48 | level.Debug(logger).Log("msg", "Ignoring device", "device", dev) 49 | continue 50 | } 51 | if accept != nil && !accept.MatchString(dev) { 52 | level.Debug(logger).Log("msg", "Ignoring device", "device", dev) 53 | continue 54 | } 55 | 56 | devStats := map[string]string{} 57 | data := (*C.struct_if_data)(ifa.ifa_data) 58 | 59 | devStats["receive_packets"] = strconv.Itoa(int(data.ifi_ipackets)) 60 | devStats["transmit_packets"] = strconv.Itoa(int(data.ifi_opackets)) 61 | devStats["receive_errs"] = strconv.Itoa(int(data.ifi_ierrors)) 62 | devStats["transmit_errs"] = strconv.Itoa(int(data.ifi_oerrors)) 63 | devStats["receive_bytes"] = strconv.Itoa(int(data.ifi_ibytes)) 64 | devStats["transmit_bytes"] = strconv.Itoa(int(data.ifi_obytes)) 65 | devStats["receive_multicast"] = strconv.Itoa(int(data.ifi_imcasts)) 66 | devStats["transmit_multicast"] = strconv.Itoa(int(data.ifi_omcasts)) 67 | devStats["receive_drop"] = strconv.Itoa(int(data.ifi_iqdrops)) 68 | netDev[dev] = devStats 69 | } 70 | } 71 | 72 | return netDev, nil 73 | } 74 | -------------------------------------------------------------------------------- /collector/netstat_linux_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package collector 15 | 16 | import ( 17 | "os" 18 | "testing" 19 | ) 20 | 21 | func TestNetStats(t *testing.T) { 22 | testNetStats(t, "fixtures/proc/net/netstat") 23 | testSNMPStats(t, "fixtures/proc/net/snmp") 24 | testSNMP6Stats(t, "fixtures/proc/net/snmp6") 25 | } 26 | 27 | func testNetStats(t *testing.T, fileName string) { 28 | file, err := os.Open(fileName) 29 | if err != nil { 30 | t.Fatal(err) 31 | } 32 | defer file.Close() 33 | 34 | netStats, err := parseNetStats(file, fileName) 35 | if err != nil { 36 | t.Fatal(err) 37 | } 38 | 39 | if want, got := "102471", netStats["TcpExt"]["DelayedACKs"]; want != got { 40 | t.Errorf("want netstat TCP DelayedACKs %s, got %s", want, got) 41 | } 42 | 43 | if want, got := "2786264347", netStats["IpExt"]["OutOctets"]; want != got { 44 | t.Errorf("want netstat IP OutOctets %s, got %s", want, got) 45 | } 46 | } 47 | 48 | func testSNMPStats(t *testing.T, fileName string) { 49 | file, err := os.Open(fileName) 50 | if err != nil { 51 | t.Fatal(err) 52 | } 53 | defer file.Close() 54 | 55 | snmpStats, err := parseNetStats(file, fileName) 56 | if err != nil { 57 | t.Fatal(err) 58 | } 59 | 60 | if want, got := "9", snmpStats["Udp"]["RcvbufErrors"]; want != got { 61 | t.Errorf("want netstat Udp RcvbufErrors %s, got %s", want, got) 62 | } 63 | 64 | if want, got := "8", snmpStats["Udp"]["SndbufErrors"]; want != got { 65 | t.Errorf("want netstat Udp SndbufErrors %s, got %s", want, got) 66 | } 67 | } 68 | 69 | func testSNMP6Stats(t *testing.T, fileName string) { 70 | file, err := os.Open(fileName) 71 | if err != nil { 72 | t.Fatal(err) 73 | } 74 | defer file.Close() 75 | 76 | snmp6Stats, err := parseSNMP6Stats(file) 77 | if err != nil { 78 | t.Fatal(err) 79 | } 80 | 81 | if want, got := "460", snmp6Stats["Ip6"]["InOctets"]; want != got { 82 | t.Errorf("want netstat IPv6 InOctets %s, got %s", want, got) 83 | } 84 | 85 | if want, got := "8", snmp6Stats["Icmp6"]["OutMsgs"]; want != got { 86 | t.Errorf("want netstat ICPM6 OutMsgs %s, got %s", want, got) 87 | } 88 | 89 | if want, got := "9", snmp6Stats["Udp6"]["RcvbufErrors"]; want != got { 90 | t.Errorf("want netstat Udp6 RcvbufErrors %s, got %s", want, got) 91 | } 92 | 93 | if want, got := "8", snmp6Stats["Udp6"]["SndbufErrors"]; want != got { 94 | t.Errorf("want netstat Udp6 SndbufErrors %s, got %s", want, got) 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /collector/paths.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package collector 15 | 16 | import ( 17 | "path/filepath" 18 | "strings" 19 | 20 | "github.com/prometheus/procfs" 21 | kingpin "gopkg.in/alecthomas/kingpin.v2" 22 | ) 23 | 24 | var ( 25 | // The path of the proc filesystem. 26 | procPath = kingpin.Flag("path.procfs", "procfs mountpoint.").Default(procfs.DefaultMountPoint).String() 27 | sysPath = kingpin.Flag("path.sysfs", "sysfs mountpoint.").Default("/sys").String() 28 | rootfsPath = kingpin.Flag("path.rootfs", "rootfs mountpoint.").Default("/").String() 29 | ) 30 | 31 | func procFilePath(name string) string { 32 | return filepath.Join(*procPath, name) 33 | } 34 | 35 | func sysFilePath(name string) string { 36 | return filepath.Join(*sysPath, name) 37 | } 38 | 39 | func rootfsFilePath(name string) string { 40 | return filepath.Join(*rootfsPath, name) 41 | } 42 | 43 | func rootfsStripPrefix(path string) string { 44 | if *rootfsPath == "/" { 45 | return path 46 | } 47 | stripped := strings.TrimPrefix(path, *rootfsPath) 48 | if stripped == "" { 49 | return "/" 50 | } 51 | return stripped 52 | } 53 | -------------------------------------------------------------------------------- /collector/paths_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package collector 15 | 16 | import ( 17 | "testing" 18 | 19 | "github.com/prometheus/procfs" 20 | "gopkg.in/alecthomas/kingpin.v2" 21 | ) 22 | 23 | func TestDefaultProcPath(t *testing.T) { 24 | if _, err := kingpin.CommandLine.Parse([]string{"--path.procfs", procfs.DefaultMountPoint}); err != nil { 25 | t.Fatal(err) 26 | } 27 | 28 | if got, want := procFilePath("somefile"), "/proc/somefile"; got != want { 29 | t.Errorf("Expected: %s, Got: %s", want, got) 30 | } 31 | 32 | if got, want := procFilePath("some/file"), "/proc/some/file"; got != want { 33 | t.Errorf("Expected: %s, Got: %s", want, got) 34 | } 35 | } 36 | 37 | func TestCustomProcPath(t *testing.T) { 38 | if _, err := kingpin.CommandLine.Parse([]string{"--path.procfs", "./../some/./place/"}); err != nil { 39 | t.Fatal(err) 40 | } 41 | 42 | if got, want := procFilePath("somefile"), "../some/place/somefile"; got != want { 43 | t.Errorf("Expected: %s, Got: %s", want, got) 44 | } 45 | 46 | if got, want := procFilePath("some/file"), "../some/place/some/file"; got != want { 47 | t.Errorf("Expected: %s, Got: %s", want, got) 48 | } 49 | } 50 | 51 | func TestDefaultSysPath(t *testing.T) { 52 | if _, err := kingpin.CommandLine.Parse([]string{"--path.sysfs", "/sys"}); err != nil { 53 | t.Fatal(err) 54 | } 55 | 56 | if got, want := sysFilePath("somefile"), "/sys/somefile"; got != want { 57 | t.Errorf("Expected: %s, Got: %s", want, got) 58 | } 59 | 60 | if got, want := sysFilePath("some/file"), "/sys/some/file"; got != want { 61 | t.Errorf("Expected: %s, Got: %s", want, got) 62 | } 63 | } 64 | 65 | func TestCustomSysPath(t *testing.T) { 66 | if _, err := kingpin.CommandLine.Parse([]string{"--path.sysfs", "./../some/./place/"}); err != nil { 67 | t.Fatal(err) 68 | } 69 | 70 | if got, want := sysFilePath("somefile"), "../some/place/somefile"; got != want { 71 | t.Errorf("Expected: %s, Got: %s", want, got) 72 | } 73 | 74 | if got, want := sysFilePath("some/file"), "../some/place/some/file"; got != want { 75 | t.Errorf("Expected: %s, Got: %s", want, got) 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /collector/processes_linux_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !noprocesses 15 | 16 | package collector 17 | 18 | import ( 19 | "github.com/go-kit/kit/log" 20 | "testing" 21 | 22 | "github.com/prometheus/procfs" 23 | kingpin "gopkg.in/alecthomas/kingpin.v2" 24 | ) 25 | 26 | func TestReadProcessStatus(t *testing.T) { 27 | if _, err := kingpin.CommandLine.Parse([]string{"--path.procfs", "fixtures/proc"}); err != nil { 28 | t.Fatal(err) 29 | } 30 | want := 1 31 | fs, err := procfs.NewFS(*procPath) 32 | if err != nil { 33 | t.Errorf("failed to open procfs: %v", err) 34 | } 35 | c := processCollector{fs: fs, logger: log.NewNopLogger()} 36 | pids, states, threads, err := c.getAllocatedThreads() 37 | if err != nil { 38 | t.Fatalf("Cannot retrieve data from procfs getAllocatedThreads function: %v ", err) 39 | } 40 | if threads < want { 41 | t.Fatalf("Current threads: %d Shouldn't be less than wanted %d", threads, want) 42 | } 43 | if states == nil { 44 | 45 | t.Fatalf("Process states cannot be nil %v:", states) 46 | } 47 | maxPid, err := readUintFromFile(procFilePath("sys/kernel/pid_max")) 48 | if err != nil { 49 | t.Fatalf("Unable to retrieve limit number of maximum pids alloved %v\n", err) 50 | } 51 | if uint64(pids) > maxPid || pids == 0 { 52 | t.Fatalf("Total running pids cannot be greater than %d or equals to 0", maxPid) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /collector/rapl_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !norapl 15 | 16 | package collector 17 | 18 | import ( 19 | "strconv" 20 | 21 | "github.com/go-kit/kit/log" 22 | "github.com/prometheus/client_golang/prometheus" 23 | "github.com/prometheus/procfs/sysfs" 24 | ) 25 | 26 | type raplCollector struct { 27 | fs sysfs.FS 28 | } 29 | 30 | func init() { 31 | registerCollector("rapl", defaultEnabled, NewRaplCollector) 32 | } 33 | 34 | // NewRaplCollector returns a new Collector exposing RAPL metrics. 35 | func NewRaplCollector(logger log.Logger) (Collector, error) { 36 | fs, err := sysfs.NewFS(*sysPath) 37 | 38 | if err != nil { 39 | return nil, err 40 | } 41 | 42 | collector := raplCollector{ 43 | fs: fs, 44 | } 45 | return &collector, nil 46 | } 47 | 48 | // Update implements Collector and exposes RAPL related metrics. 49 | func (c *raplCollector) Update(ch chan<- prometheus.Metric) error { 50 | // nil zones are fine when platform doesn't have powercap files present. 51 | zones, err := sysfs.GetRaplZones(c.fs) 52 | if err != nil { 53 | return nil 54 | } 55 | 56 | for _, rz := range zones { 57 | newMicrojoules, err := rz.GetEnergyMicrojoules() 58 | if err != nil { 59 | return err 60 | } 61 | index := strconv.Itoa(rz.Index) 62 | 63 | descriptor := prometheus.NewDesc( 64 | prometheus.BuildFQName(namespace, "rapl", rz.Name+"_joules_total"), 65 | "Current RAPL "+rz.Name+" value in joules", 66 | []string{"index"}, nil, 67 | ) 68 | 69 | ch <- prometheus.MustNewConstMetric( 70 | descriptor, 71 | prometheus.CounterValue, 72 | float64(newMicrojoules)/1000000.0, 73 | index, 74 | ) 75 | } 76 | return nil 77 | } 78 | -------------------------------------------------------------------------------- /collector/time.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !notime 15 | 16 | package collector 17 | 18 | import ( 19 | "time" 20 | 21 | "github.com/go-kit/kit/log" 22 | "github.com/go-kit/kit/log/level" 23 | "github.com/prometheus/client_golang/prometheus" 24 | ) 25 | 26 | type timeCollector struct { 27 | desc *prometheus.Desc 28 | logger log.Logger 29 | } 30 | 31 | func init() { 32 | registerCollector("time", defaultEnabled, NewTimeCollector) 33 | } 34 | 35 | // NewTimeCollector returns a new Collector exposing the current system time in 36 | // seconds since epoch. 37 | func NewTimeCollector(logger log.Logger) (Collector, error) { 38 | return &timeCollector{ 39 | desc: prometheus.NewDesc( 40 | namespace+"_time_seconds", 41 | "System time in seconds since epoch (1970).", 42 | nil, nil, 43 | ), 44 | logger: logger, 45 | }, nil 46 | } 47 | 48 | func (c *timeCollector) Update(ch chan<- prometheus.Metric) error { 49 | now := float64(time.Now().UnixNano()) / 1e9 50 | level.Debug(c.logger).Log("msg", "Return time", "now", now) 51 | ch <- prometheus.MustNewConstMetric(c.desc, prometheus.GaugeValue, now) 52 | return nil 53 | } 54 | -------------------------------------------------------------------------------- /collector/udp_queues_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !noudp_queues 15 | 16 | package collector 17 | 18 | import ( 19 | "errors" 20 | "fmt" 21 | "os" 22 | 23 | "github.com/go-kit/kit/log" 24 | "github.com/go-kit/kit/log/level" 25 | "github.com/prometheus/client_golang/prometheus" 26 | "github.com/prometheus/procfs" 27 | ) 28 | 29 | type ( 30 | udpQueuesCollector struct { 31 | fs procfs.FS 32 | desc *prometheus.Desc 33 | logger log.Logger 34 | } 35 | ) 36 | 37 | func init() { 38 | registerCollector("udp_queues", defaultEnabled, NewUDPqueuesCollector) 39 | } 40 | 41 | // NewUDPqueuesCollector returns a new Collector exposing network udp queued bytes. 42 | func NewUDPqueuesCollector(logger log.Logger) (Collector, error) { 43 | fs, err := procfs.NewFS(*procPath) 44 | if err != nil { 45 | return nil, fmt.Errorf("failed to open procfs: %w", err) 46 | } 47 | return &udpQueuesCollector{ 48 | fs: fs, 49 | desc: prometheus.NewDesc( 50 | prometheus.BuildFQName(namespace, "udp", "queues"), 51 | "Number of allocated memory in the kernel for UDP datagrams in bytes.", 52 | []string{"queue", "ip"}, nil, 53 | ), 54 | logger: logger, 55 | }, nil 56 | } 57 | 58 | func (c *udpQueuesCollector) Update(ch chan<- prometheus.Metric) error { 59 | 60 | s4, errIPv4 := c.fs.NetUDPSummary() 61 | if errIPv4 == nil { 62 | ch <- prometheus.MustNewConstMetric(c.desc, prometheus.GaugeValue, float64(s4.TxQueueLength), "tx", "v4") 63 | ch <- prometheus.MustNewConstMetric(c.desc, prometheus.GaugeValue, float64(s4.RxQueueLength), "rx", "v4") 64 | } else { 65 | if errors.Is(errIPv4, os.ErrNotExist) { 66 | level.Debug(c.logger).Log("msg", "not collecting ipv4 based metrics") 67 | } else { 68 | return fmt.Errorf("couldn't get udp queued bytes: %w", errIPv4) 69 | } 70 | } 71 | 72 | s6, errIPv6 := c.fs.NetUDP6Summary() 73 | if errIPv6 == nil { 74 | ch <- prometheus.MustNewConstMetric(c.desc, prometheus.GaugeValue, float64(s6.TxQueueLength), "tx", "v6") 75 | ch <- prometheus.MustNewConstMetric(c.desc, prometheus.GaugeValue, float64(s6.RxQueueLength), "rx", "v6") 76 | } else { 77 | if errors.Is(errIPv6, os.ErrNotExist) { 78 | level.Debug(c.logger).Log("msg", "not collecting ipv6 based metrics") 79 | } else { 80 | return fmt.Errorf("couldn't get udp6 queued bytes: %w", errIPv6) 81 | } 82 | } 83 | 84 | if errors.Is(errIPv4, os.ErrNotExist) && errors.Is(errIPv6, os.ErrNotExist) { 85 | return ErrNoData 86 | } 87 | return nil 88 | } 89 | -------------------------------------------------------------------------------- /collector/uname.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build darwin freebsd openbsd linux 15 | // +build !nouname 16 | 17 | package collector 18 | 19 | import ( 20 | "github.com/go-kit/kit/log" 21 | "github.com/prometheus/client_golang/prometheus" 22 | ) 23 | 24 | var unameDesc = prometheus.NewDesc( 25 | prometheus.BuildFQName(namespace, "uname", "info"), 26 | "Labeled system information as provided by the uname system call.", 27 | []string{ 28 | "sysname", 29 | "release", 30 | "version", 31 | "machine", 32 | "nodename", 33 | "domainname", 34 | }, 35 | nil, 36 | ) 37 | 38 | type unameCollector struct { 39 | logger log.Logger 40 | } 41 | type uname struct { 42 | SysName string 43 | Release string 44 | Version string 45 | Machine string 46 | NodeName string 47 | DomainName string 48 | } 49 | 50 | func init() { 51 | registerCollector("uname", defaultEnabled, newUnameCollector) 52 | } 53 | 54 | // NewUnameCollector returns new unameCollector. 55 | func newUnameCollector(logger log.Logger) (Collector, error) { 56 | return &unameCollector{logger}, nil 57 | } 58 | 59 | func (c *unameCollector) Update(ch chan<- prometheus.Metric) error { 60 | uname, err := getUname() 61 | if err != nil { 62 | return err 63 | } 64 | 65 | ch <- prometheus.MustNewConstMetric(unameDesc, prometheus.GaugeValue, 1, 66 | uname.SysName, 67 | uname.Release, 68 | uname.Version, 69 | uname.Machine, 70 | uname.NodeName, 71 | uname.DomainName, 72 | ) 73 | 74 | return nil 75 | } 76 | -------------------------------------------------------------------------------- /collector/uname_bsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build darwin freebsd openbsd 15 | // +build !nouname 16 | 17 | package collector 18 | 19 | import ( 20 | "bytes" 21 | "strings" 22 | 23 | "golang.org/x/sys/unix" 24 | ) 25 | 26 | func getUname() (uname, error) { 27 | var utsname unix.Utsname 28 | if err := unix.Uname(&utsname); err != nil { 29 | return uname{}, err 30 | } 31 | 32 | nodeName, domainName := parseHostNameAndDomainName(utsname) 33 | 34 | output := uname{ 35 | SysName: string(utsname.Sysname[:bytes.IndexByte(utsname.Sysname[:], 0)]), 36 | Release: string(utsname.Release[:bytes.IndexByte(utsname.Release[:], 0)]), 37 | Version: string(utsname.Version[:bytes.IndexByte(utsname.Version[:], 0)]), 38 | Machine: string(utsname.Machine[:bytes.IndexByte(utsname.Machine[:], 0)]), 39 | NodeName: nodeName, 40 | DomainName: domainName, 41 | } 42 | 43 | return output, nil 44 | } 45 | 46 | // parseHostNameAndDomainName for FreeBSD,OpenBSD,Darwin. 47 | // Attempts to emulate what happens in the Linux uname calls since these OS doesn't have a Domainname. 48 | func parseHostNameAndDomainName(utsname unix.Utsname) (hostname string, domainname string) { 49 | nodename := string(utsname.Nodename[:bytes.IndexByte(utsname.Nodename[:], 0)]) 50 | split := strings.SplitN(nodename, ".", 2) 51 | 52 | // We'll always have at least a single element in the array. We assume this 53 | // is the hostname. 54 | hostname = split[0] 55 | 56 | // If we have more than one element, we assume this is the domainname. 57 | // Otherwise leave it to "(none)" like Linux. 58 | domainname = "(none)" 59 | if len(split) > 1 { 60 | domainname = split[1] 61 | } 62 | return hostname, domainname 63 | } 64 | -------------------------------------------------------------------------------- /collector/uname_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !nouname 15 | 16 | package collector 17 | 18 | import ( 19 | "bytes" 20 | 21 | "golang.org/x/sys/unix" 22 | ) 23 | 24 | func getUname() (uname, error) { 25 | var utsname unix.Utsname 26 | if err := unix.Uname(&utsname); err != nil { 27 | return uname{}, err 28 | } 29 | 30 | output := uname{ 31 | SysName: string(utsname.Sysname[:bytes.IndexByte(utsname.Sysname[:], 0)]), 32 | Release: string(utsname.Release[:bytes.IndexByte(utsname.Release[:], 0)]), 33 | Version: string(utsname.Version[:bytes.IndexByte(utsname.Version[:], 0)]), 34 | Machine: string(utsname.Machine[:bytes.IndexByte(utsname.Machine[:], 0)]), 35 | NodeName: string(utsname.Nodename[:bytes.IndexByte(utsname.Nodename[:], 0)]), 36 | DomainName: string(utsname.Domainname[:bytes.IndexByte(utsname.Domainname[:], 0)]), 37 | } 38 | 39 | return output, nil 40 | } 41 | -------------------------------------------------------------------------------- /collector/vmstat_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | // +build !novmstat 15 | 16 | package collector 17 | 18 | import ( 19 | "bufio" 20 | "fmt" 21 | "os" 22 | "regexp" 23 | "strconv" 24 | "strings" 25 | 26 | "github.com/go-kit/kit/log" 27 | "github.com/prometheus/client_golang/prometheus" 28 | "gopkg.in/alecthomas/kingpin.v2" 29 | ) 30 | 31 | const ( 32 | vmStatSubsystem = "vmstat" 33 | ) 34 | 35 | var ( 36 | vmStatFields = kingpin.Flag("collector.vmstat.fields", "Regexp of fields to return for vmstat collector.").Default("^(oom_kill|pgpg|pswp|pg.*fault).*").String() 37 | ) 38 | 39 | type vmStatCollector struct { 40 | fieldPattern *regexp.Regexp 41 | logger log.Logger 42 | } 43 | 44 | func init() { 45 | registerCollector("vmstat", defaultEnabled, NewvmStatCollector) 46 | } 47 | 48 | // NewvmStatCollector returns a new Collector exposing vmstat stats. 49 | func NewvmStatCollector(logger log.Logger) (Collector, error) { 50 | pattern := regexp.MustCompile(*vmStatFields) 51 | return &vmStatCollector{ 52 | fieldPattern: pattern, 53 | logger: logger, 54 | }, nil 55 | } 56 | 57 | func (c *vmStatCollector) Update(ch chan<- prometheus.Metric) error { 58 | file, err := os.Open(procFilePath("vmstat")) 59 | if err != nil { 60 | return err 61 | } 62 | defer file.Close() 63 | 64 | scanner := bufio.NewScanner(file) 65 | for scanner.Scan() { 66 | parts := strings.Fields(scanner.Text()) 67 | value, err := strconv.ParseFloat(parts[1], 64) 68 | if err != nil { 69 | return err 70 | } 71 | if !c.fieldPattern.MatchString(parts[0]) { 72 | continue 73 | } 74 | 75 | ch <- prometheus.MustNewConstMetric( 76 | prometheus.NewDesc( 77 | prometheus.BuildFQName(namespace, vmStatSubsystem, parts[0]), 78 | fmt.Sprintf("/proc/vmstat information field %s.", parts[0]), 79 | nil, nil), 80 | prometheus.UntypedValue, 81 | value, 82 | ) 83 | } 84 | return scanner.Err() 85 | } 86 | -------------------------------------------------------------------------------- /docs/V0_16_UPGRADE_GUIDE.md: -------------------------------------------------------------------------------- 1 | # Version 0.16.0 Upgrade Guide 2 | 3 | The `node_exporter` 0.16.0 and newer renamed many metrics in order to conform with Prometheus [naming best practices]. 4 | 5 | In order to allow easy upgrades, there are several options. 6 | 7 | ## Update dashboards 8 | 9 | Grafana users can add multiple queries in order to display both the old and new data simultaneously. 10 | 11 | ## Use recording rules 12 | 13 | We have provided a [sample recording rule set that translates old metrics to new ones] and the [one that translates new metrics format to old one] to create duplicate metrics (it translates "old" metrics format to new one). This has a minor disadvantage that it creates a lot of extra data, and re-aligns the timestamps of the data. 14 | 15 | ## Run both old and new versions simultaneously. 16 | 17 | It's possible to run both the old and new exporter on different ports, and include an additional scrape job in Prometheus. It's recommended to enable only the collectors that have name changes that you care about. 18 | 19 | [naming best practices]: https://prometheus.io/docs/practices/naming/ 20 | [sample recording rule set that translates old metrics to new ones]: example-16-compatibility-rules.yml 21 | [one that translates new metrics format to old one]: example-16-compatibility-rules-new-to-old.yml 22 | -------------------------------------------------------------------------------- /docs/example-17-compatibility-rules-new-to-old.yml: -------------------------------------------------------------------------------- 1 | groups: 2 | - name: node_exporter-17-supervisord 3 | rules: 4 | - record: node_supervisord_start_time_seconds 5 | expr: node_supervisord_uptime + time() 6 | -------------------------------------------------------------------------------- /docs/example-17-compatibility-rules.yml: -------------------------------------------------------------------------------- 1 | groups: 2 | - name: node_exporter-17-supervisord 3 | rules: 4 | - record: node_supervisord_uptime 5 | expr: time() - node_supervisord_start_time_seconds 6 | -------------------------------------------------------------------------------- /docs/node-mixin/.gitignore: -------------------------------------------------------------------------------- 1 | jsonnetfile.lock.json 2 | vendor 3 | *.yaml 4 | dashboards_out 5 | -------------------------------------------------------------------------------- /docs/node-mixin/Makefile: -------------------------------------------------------------------------------- 1 | JSONNET_FMT := jsonnetfmt -n 2 --max-blank-lines 2 --string-style s --comment-style s 2 | 3 | all: fmt node_alerts.yaml node_rules.yaml dashboards_out lint 4 | 5 | fmt: 6 | find . -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \ 7 | xargs -n 1 -- $(JSONNET_FMT) -i 8 | 9 | node_alerts.yaml: mixin.libsonnet config.libsonnet $(wildcard alerts/*) 10 | jsonnet -S alerts.jsonnet > $@ 11 | 12 | node_rules.yaml: mixin.libsonnet config.libsonnet $(wildcard rules/*) 13 | jsonnet -S rules.jsonnet > $@ 14 | 15 | dashboards_out: mixin.libsonnet config.libsonnet $(wildcard dashboards/*) 16 | @mkdir -p dashboards_out 17 | jsonnet -J vendor -m dashboards_out dashboards.jsonnet 18 | 19 | lint: node_alerts.yaml node_rules.yaml 20 | find . -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \ 21 | while read f; do \ 22 | $(JSONNET_FMT) "$$f" | diff -u "$$f" -; \ 23 | done 24 | 25 | promtool check rules node_alerts.yaml node_rules.yaml 26 | 27 | clean: 28 | rm -rf dashboards_out node_alerts.yaml node_rules.yaml 29 | -------------------------------------------------------------------------------- /docs/node-mixin/README.md: -------------------------------------------------------------------------------- 1 | # Node Mixin 2 | 3 | _This is a work in progress. We aim for it to become a good role model for alerts 4 | and dashboards eventually, but it is not quite there yet._ 5 | 6 | The Node Mixin is a set of configurable, reusable, and extensible alerts and 7 | dashboards based on the metrics exported by the Node Exporter. The mixin creates 8 | recording and alerting rules for Prometheus and suitable dashboard descriptions 9 | for Grafana. 10 | 11 | To use them, you need to have `jsonnet` (v0.13+) and `jb` installed. If you 12 | have a working Go development environment, it's easiest to run the following: 13 | ```bash 14 | $ go get github.com/google/go-jsonnet/cmd/jsonnet 15 | $ go get github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb 16 | ``` 17 | 18 | _Note: The make targets `lint` and `fmt` need the `jsonnetfmt` binary, which is 19 | currently not included in the Go implementation of `jsonnet`. For the time 20 | being, you have to install the [C++ version of 21 | jsonnetfmt](https://github.com/google/jsonnet) if you want to use `make lint` 22 | or `make fmt`._ 23 | 24 | Next, install the dependencies by running the following command in this 25 | directory: 26 | ```bash 27 | $ jb install 28 | ``` 29 | 30 | You can then build the Prometheus rules files `node_alerts.yaml` and 31 | `node_rules.yaml`: 32 | ```bash 33 | $ make node_alerts.yaml node_rules.yaml 34 | ``` 35 | 36 | You can also build a directory `dashboard_out` with the JSON dashboard files 37 | for Grafana: 38 | ```bash 39 | $ make dashboards_out 40 | ``` 41 | 42 | Note that some of the generated dashboards require recording rules specified in 43 | the previously generated `node_rules.yaml`. 44 | 45 | For more advanced uses of mixins, see 46 | https://github.com/monitoring-mixins/docs. 47 | 48 | -------------------------------------------------------------------------------- /docs/node-mixin/alerts.jsonnet: -------------------------------------------------------------------------------- 1 | std.manifestYamlDoc((import 'mixin.libsonnet').prometheusAlerts) 2 | -------------------------------------------------------------------------------- /docs/node-mixin/config.libsonnet: -------------------------------------------------------------------------------- 1 | { 2 | _config+:: { 3 | // Selectors are inserted between {} in Prometheus queries. 4 | 5 | // Select the metrics coming from the node exporter. Note that all 6 | // the selected metrics are shown stacked on top of each other in 7 | // the 'USE Method / Cluster' dashboard. Consider disabling that 8 | // dashboard if mixing up all those metrics in the same dashboard 9 | // doesn't make sense (e.g. because they are coming from different 10 | // clusters). 11 | nodeExporterSelector: 'job="node"', 12 | 13 | // Select the fstype for filesystem-related queries. If left 14 | // empty, all filesystems are selected. If you have unusual 15 | // filesystem you don't want to include in dashboards and 16 | // alerting, you can exclude them here, e.g. 'fstype!="tmpfs"'. 17 | fsSelector: 'fstype!=""', 18 | 19 | // Select the device for disk-related queries. If left empty, all 20 | // devices are selected. If you have unusual devices you don't 21 | // want to include in dashboards and alerting, you can exclude 22 | // them here, e.g. 'device!="tmpfs"'. 23 | diskDeviceSelector: 'device!=""', 24 | 25 | // Some of the alerts are meant to fire if a critical failure of a 26 | // node is imminent (e.g. the disk is about to run full). In a 27 | // true “cloud native” setup, failures of a single node should be 28 | // tolerated. Hence, even imminent failure of a single node is no 29 | // reason to create a paging alert. However, in practice there are 30 | // still many situations where operators like to get paged in time 31 | // before a node runs out of disk space. nodeCriticalSeverity can 32 | // be set to the desired severity for this kind of alerts. This 33 | // can even be templated to depend on labels of the node, e.g. you 34 | // could make this critical for traditional database masters but 35 | // just a warning for K8s nodes. 36 | nodeCriticalSeverity: 'critical', 37 | 38 | // Available disk space (%) thresholds on which to trigger the 39 | // 'NodeFilesystemSpaceFillingUp' alerts. These alerts fire if the disk 40 | // usage grows in a way that it is predicted to run out in 4h or 1d 41 | // and if the provided thresholds have been reached right now. 42 | // In some cases you'll want to adjust these, e.g. by default Kubernetes 43 | // runs the image garbage collection when the disk usage reaches 85% 44 | // of its available space. In that case, you'll want to reduce the 45 | // critical threshold below to something like 14 or 15, otherwise 46 | // the alert could fire under normal node usage. 47 | fsSpaceFillingUpWarningThreshold: 40, 48 | fsSpaceFillingUpCriticalThreshold: 20, 49 | 50 | grafana_prefix: '', 51 | }, 52 | } 53 | -------------------------------------------------------------------------------- /docs/node-mixin/dashboards.jsonnet: -------------------------------------------------------------------------------- 1 | local dashboards = (import 'mixin.libsonnet').grafanaDashboards; 2 | 3 | { 4 | [name]: dashboards[name] 5 | for name in std.objectFields(dashboards) 6 | } 7 | -------------------------------------------------------------------------------- /docs/node-mixin/dashboards/dashboards.libsonnet: -------------------------------------------------------------------------------- 1 | (import 'node.libsonnet') + 2 | (import 'use.libsonnet') 3 | -------------------------------------------------------------------------------- /docs/node-mixin/jsonnetfile.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | { 4 | "name": "grafonnet", 5 | "source": { 6 | "git": { 7 | "remote": "https://github.com/grafana/grafonnet-lib", 8 | "subdir": "grafonnet" 9 | } 10 | }, 11 | "version": "master" 12 | }, 13 | { 14 | "name": "grafana-builder", 15 | "source": { 16 | "git": { 17 | "remote": "https://github.com/grafana/jsonnet-libs", 18 | "subdir": "grafana-builder" 19 | } 20 | }, 21 | "version": "master" 22 | }, 23 | { 24 | "name": "promgrafonnet", 25 | "source": { 26 | "git": { 27 | "remote": "https://github.com/kubernetes-monitoring/kubernetes-mixin", 28 | "subdir": "lib/promgrafonnet" 29 | } 30 | }, 31 | "version": "master" 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /docs/node-mixin/mixin.libsonnet: -------------------------------------------------------------------------------- 1 | (import 'config.libsonnet') + 2 | (import 'alerts/alerts.libsonnet') + 3 | (import 'dashboards/dashboards.libsonnet') + 4 | (import 'rules/rules.libsonnet') 5 | -------------------------------------------------------------------------------- /docs/node-mixin/rules.jsonnet: -------------------------------------------------------------------------------- 1 | std.manifestYamlDoc((import 'mixin.libsonnet').prometheusRules) 2 | -------------------------------------------------------------------------------- /example-rules.yml: -------------------------------------------------------------------------------- 1 | groups: 2 | - name: example-node-exporter-rules 3 | rules: 4 | # The count of CPUs per node, useful for getting CPU time as a percent of total. 5 | - record: instance:node_cpus:count 6 | expr: count(node_cpu_seconds_total{mode="idle"}) without (cpu,mode) 7 | 8 | # CPU in use by CPU. 9 | - record: instance_cpu:node_cpu_seconds_not_idle:rate5m 10 | expr: sum(rate(node_cpu_seconds_total{mode!="idle"}[5m])) without (mode) 11 | 12 | # CPU in use by mode. 13 | - record: instance_mode:node_cpu_seconds:rate5m 14 | expr: sum(rate(node_cpu_seconds_total[5m])) without (cpu) 15 | 16 | # CPU in use ratio. 17 | - record: instance:node_cpu_utilization:ratio 18 | expr: sum(instance_mode:node_cpu_seconds:rate5m{mode!="idle"}) without (mode) / instance:node_cpus:count 19 | -------------------------------------------------------------------------------- /examples/init.d/node_exporter: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | RETVAL=0 4 | PROG="node_exporter" 5 | EXEC="/etc/node_exporter/node_exporter" 6 | LOCKFILE="/var/lock/subsys/$PROG" 7 | OPTIONS="--web.listen-address=:9100" 8 | 9 | # Source function library. 10 | if [ -f /etc/rc.d/init.d/functions ]; then 11 | . /etc/rc.d/init.d/functions 12 | else 13 | echo "/etc/rc.d/init.d/functions does not exist" 14 | exit 0 15 | fi 16 | 17 | start() { 18 | if [ -f $LOCKFILE ] 19 | then 20 | echo "$PROG is already running!" 21 | else 22 | echo -n "Starting $PROG: " 23 | nohup $EXEC $OPTIONS >/dev/null 2>&1 & 24 | RETVAL=$? 25 | [ $RETVAL -eq 0 ] && touch $LOCKFILE && success || failure 26 | echo 27 | return $RETVAL 28 | fi 29 | } 30 | 31 | stop() { 32 | echo -n "Stopping $PROG: " 33 | killproc $EXEC 34 | RETVAL=$? 35 | [ $RETVAL -eq 0 ] && rm -r $LOCKFILE && success || failure 36 | echo 37 | } 38 | 39 | restart () 40 | { 41 | stop 42 | sleep 1 43 | start 44 | } 45 | 46 | case "$1" in 47 | start) 48 | start 49 | ;; 50 | stop) 51 | stop 52 | ;; 53 | status) 54 | status $PROG 55 | ;; 56 | restart) 57 | restart 58 | ;; 59 | *) 60 | echo "Usage: $0 {start|stop|restart|status}" 61 | exit 1 62 | esac 63 | exit $RETVAL 64 | -------------------------------------------------------------------------------- /examples/launchctl/README.md: -------------------------------------------------------------------------------- 1 | # MacOS LaunchDaemon 2 | 3 | If you're installing through a package manager, you probably don't need to deal 4 | with this file. 5 | 6 | The `plist` file should be put in `/Library/LaunchDaemons/` (user defined daemons), and the binary installed at 7 | `/usr/local/bin/node_exporter`. 8 | 9 | Ex. install globally by 10 | 11 | sudo cp -n node_exporter /usr/local/bin/ 12 | sudo cp -n examples/launchctl/io.prometheus.node_exporter.plist /Library/LaunchDaemons/ 13 | sudo launchctl bootstrap system/ /Library/LaunchDaemons/io.prometheus.node_exporter.plist 14 | 15 | # Optionally configure by dropping CLI arguments in a file 16 | echo -- '--web.listen-address=:9101' | sudo tee /usr/local/etc/node_exporter.args 17 | 18 | # Check it's running 19 | sudo launchctl list | grep node_exporter 20 | 21 | # See full process state 22 | sudo launchctl print system/io.prometheus.node_exporter 23 | 24 | # View logs 25 | sudo tail /tmp/node_exporter.log 26 | -------------------------------------------------------------------------------- /examples/launchctl/io.prometheus.node_exporter.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Label 6 | io.prometheus.node_exporter 7 | ProgramArguments 8 | 9 | sh 10 | -c 11 | /usr/local/bin/node_exporter $(< /usr/local/etc/node_exporter.args) 12 | 13 | UserName 14 | nobody 15 | GroupName 16 | nobody 17 | RunAtLoad 18 | 19 | KeepAlive 20 | 21 | WorkingDirectory 22 | /usr/local 23 | StandardErrorPath 24 | /tmp/node_exporter.log 25 | StandardOutPath 26 | /tmp/node_exporter.log 27 | HardResourceLimits 28 | 29 | NumberOfFiles 30 | 4096 31 | 32 | SoftResourceLimits 33 | 34 | NumberOfFiles 35 | 4096 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /examples/openbsd-rc.d/node_exporter: -------------------------------------------------------------------------------- 1 | #!/bin/ksh 2 | # Shawn Craver, 2019-04-02 3 | 4 | 5 | daemon="/usr/local/bin/node_exporter" 6 | 7 | . /etc/rc.d/rc.subr 8 | 9 | rc_bg=YES 10 | 11 | rc_cmd $1 12 | 13 | -------------------------------------------------------------------------------- /examples/openwrt-init.d/node_exporter: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | 3 | START=99 4 | 5 | USE_PROCD=1 6 | PROG="/usr/bin/node_exporter" 7 | OPTIONS="--web.listen-address=:9100" 8 | 9 | start_service() { 10 | procd_open_instance 11 | procd_set_param command "$PROG" "${OPTIONS}" 12 | procd_close_instance 13 | } 14 | -------------------------------------------------------------------------------- /examples/systemd/README.md: -------------------------------------------------------------------------------- 1 | # Systemd Unit 2 | 3 | If you are using distribution packages or the copr repository, you don't need to deal with these files! 4 | 5 | The unit file in this directory is to be put into `/etc/systemd/system`. 6 | It needs a user named `node_exporter`, whose shell should be `/sbin/nologin` and should not have any special privileges. 7 | It needs a sysconfig file in `/etc/sysconfig/node_exporter`. 8 | It needs a directory named `/var/lib/node_exporter/textfile_collector`, whose owner should be `node_exporter`:`node_exporter`. 9 | A sample file can be found in `sysconfig.node_exporter`. 10 | -------------------------------------------------------------------------------- /examples/systemd/node_exporter.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Node Exporter 3 | 4 | [Service] 5 | User=node_exporter 6 | EnvironmentFile=/etc/sysconfig/node_exporter 7 | ExecStart=/usr/sbin/node_exporter $OPTIONS 8 | 9 | [Install] 10 | WantedBy=multi-user.target 11 | -------------------------------------------------------------------------------- /examples/systemd/sysconfig.node_exporter: -------------------------------------------------------------------------------- 1 | OPTIONS="--collector.textfile.directory /var/lib/node_exporter/textfile_collector" 2 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/prometheus/node_exporter 2 | 3 | require ( 4 | github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect 5 | github.com/beevik/ntp v0.3.0 6 | github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf 7 | github.com/ema/qdisc v0.0.0-20200603082823-62d0308e3e00 8 | github.com/go-kit/kit v0.10.0 9 | github.com/godbus/dbus v0.0.0-20190402143921-271e53dc4968 10 | github.com/golang/protobuf v1.4.1 // indirect 11 | github.com/hodgesds/perf-utils v0.0.8 12 | github.com/jpillora/backoff v1.0.0 // indirect 13 | github.com/lufia/iostat v1.1.0 14 | github.com/mattn/go-xmlrpc v0.0.3 15 | github.com/mdlayher/genetlink v1.0.0 // indirect 16 | github.com/mdlayher/netlink v1.1.0 // indirect 17 | github.com/mdlayher/wifi v0.0.0-20190303161829-b1436901ddee 18 | github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect 19 | github.com/pkg/errors v0.9.1 20 | github.com/prometheus/client_golang v1.6.0 21 | github.com/prometheus/client_model v0.2.0 22 | github.com/prometheus/common v0.10.0 23 | github.com/prometheus/procfs v0.1.3 24 | github.com/siebenmann/go-kstat v0.0.0-20200303194639-4e8294f9e9d5 25 | github.com/soundcloud/go-runit v0.0.0-20150630195641-06ad41a06c4a 26 | go.uber.org/multierr v1.5.0 // indirect 27 | golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 28 | golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect 29 | golang.org/x/net v0.0.0-20200602114024-627f9648deb9 // indirect 30 | golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a // indirect 31 | golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 32 | golang.org/x/tools v0.0.0-20200513201620-d5fe73897c97 // indirect 33 | gopkg.in/alecthomas/kingpin.v2 v2.2.6 34 | gopkg.in/yaml.v2 v2.3.0 35 | honnef.co/go/tools v0.0.1-2020.1.3 // indirect 36 | ) 37 | 38 | go 1.14 39 | -------------------------------------------------------------------------------- /https/testdata/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC9bLZ/0S++5EHr 3 | Xf9QeAMrdgPaAUggE5Bmyc5uBuX6LQ3AsEYoRBCgYXmHophMKfr5uw9Ex5BcXFVg 4 | zUXauOTdKHLIi6E+SwAJgrAs3NYXyQL0zSbHESjzd7WXwnbC4AfXNFvg7RpZpbS3 5 | Fgk9Nb3ZAwedfDvwY71eApnPMuGsTHo+TLKOmGgHT1ncDb/MgwRc2JDwc9orCBfE 6 | NqfYlD22wK8pCtMZX+t9zE0FVhEK7rHz18laPIxXFpFRFPggTg8pngQh5vHk6ESv 7 | 1yWSCGT8LBwuT3FTkVMd5fl7Ug8h2lzdGWiWynBq8cQNB6/4ZROS6e9ls4mG/cB0 8 | XKRrSWLFAgMBAAECggEAezQ0V1o11dEc1vuiTjJgzWnLA4aF5OcUquZjb8jo2Blp 9 | soR0fUgYEFiV9RRaPl+nr7ptKe0rBgfAOGALKUHNCdN/JNU8oQmjEoyADg3s6jeB 10 | xruQlzWgDwszf2uqVwHj16Nkhx1wYBKZQeQBSmCkBHwl/daKHcahqn3CkLOleKx+ 11 | Qlc3BzWNaGte6qpJMs0It3by1FuxRwVz5VkL8uhzj0WIOYMA84t0gTnFH9gfRO3F 12 | licotxg/Nl5M36wWcfL8Jq++72AtaKcD1jUEwuQpogrVeqflmeHwn/TlL++Hv6Xe 13 | Lq0jt3OCUKUV40eq9c5uEgTmyrVHMDkfFdXzutdMAQKBgQDsSMXk7P4SX6u6uTjV 14 | In9eWw6ZyJ2aL6VB9co/NMsj49GrrFT8VX9d+JPe9P/n6tuGcFbymNep22njRksR 15 | 0ItpW1NFRR/R3g0kYe1EhkRpNm6fhY9oIuR9xhcNnPNYkqAKT3T/dxrzbwsNhomi 16 | X8aht/eCz4ZsK/KdOGTkPozxgQKBgQDNOvrclT1Wl4bxONp9pEV5XpRSD/qigfIp 17 | i5wxy7ihX/QY9RToIWJDnzMVLnEYe64RB2WB8/4WwNPOQcuaxXbFUFct/2NdhTnS 18 | ToJPgPe819zW9t1FLTf1fHtsRBpGFtbhdlUDOiOtJiMXYiwlRh2uyWFhjOo8TNUE 19 | qMwai0vLRQKBgQCDH4t6lC4W4jK5x2oLlT5bjWqX2uXjF8e8x/q5gsGspBPKEjOD 20 | aKrq6jSdSRbui73RaGxH6pvb7iBf+LVWKIYFLKIUUdzrqS9f3lw+Z8h1HrjbG9JO 21 | dvaX+aL3cf71S0E3F4sU7fLt3tSiZ+PfUQk424+mbyXox6a2qwIKS9AJgQKBgHCu 22 | dHROYJo9ojKpo5Ueb6K+4jLYYSV+sYZMCBtzHlFETNKzJaJ6SeiU7Ugw8pmdtqnU 23 | 5M/gNl8pymFR0MeOqbKWdPdlZJpBfsjQoE2kouEFqFRCwKStui7IBUAheEeJXLv3 24 | 659U+aek69l35oMkp0GDgjs8UpN/H+pp/36Hgrr9AoGAftWU405rpStHEdRVrazP 25 | FibQesT9HOdJgmm1gNIhj+PnFs7lKER9p0Wdl79QnIqjwyhjCXL94TFerzTKLY2c 26 | IRj5dcRHiiT0iK8wq8bzGNYCqV73oQXaUFMiutNAArXwzwuvPFPWNBQsjLzeDLeC 27 | mcOsCcPAk8cLYtVfZo2sP3g= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /https/testdata/tls_config_auth_clientCAs_invalid.bad.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "testdata/server.crt" 3 | key_file : "testdata/server.key" 4 | client_ca_file : "somefile" -------------------------------------------------------------------------------- /https/testdata/tls_config_auth_clientCAs_missing.bad.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "testdata/server.crt" 3 | key_file : "testdata/server.key" 4 | client_auth_type : "RequireAndVerifyClientCert" -------------------------------------------------------------------------------- /https/testdata/tls_config_auth_user_list_invalid.bad.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "testdata/server.crt" 3 | key_file : "testdata/server.key" 4 | basic_auth_users: 5 | john: doe 6 | -------------------------------------------------------------------------------- /https/testdata/tls_config_empty.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twosson/fil_exporter/260c90af3b6a6b03b19620d855c85aed5a6fcc92/https/testdata/tls_config_empty.yml -------------------------------------------------------------------------------- /https/testdata/tls_config_junk.yml: -------------------------------------------------------------------------------- 1 | hWkNKCp3fvIx3jKnsaBI 2 | TuEjdwNS8A2vYdFbiKqr 3 | ay3RiOtykgt4m6m3KOol 4 | ZreGpJRGmpDSVV9cioiF 5 | r7kDOHhHU2frvv0nLcY2 6 | uQMQM4XgqFkCG6gFAIJZ 7 | g99tTkrZhN9b6pkJ6J2y 8 | rzdt729HrA2RblDGYfjs 9 | MW7GxrBdlCnliYJGPhfr 10 | g9kaXxMXcDwsw0C0rv0u 11 | 637ZmfRGElb6VBVOtgqn 12 | RG0MRezjLYCJQBMUdRDE 13 | RzO4VicAzj7asVZAT3oo 14 | nPw267UONk7h7KBYRgch 15 | Alj38foWqjV3heXXdahm 16 | TrMzMgl6JIQ1x4OZB5i4 17 | qlrXFJoeV6Pr77nuiEh9 18 | 3yE5vMnnKHm2nImEfzMG 19 | bI01UDObHRSaoJLC0vTD 20 | G9tlcKU883NkQ6nsxJ8Y 21 | -------------------------------------------------------------------------------- /https/testdata/tls_config_junk_key.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_filse: "testdata/server.crt" 3 | -------------------------------------------------------------------------------- /https/testdata/tls_config_noAuth.bad.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "testdata/server.crt" 3 | key_file : "testdata/server.key" 4 | client_ca_file : "testdata/tls-ca-chain.pem" 5 | -------------------------------------------------------------------------------- /https/testdata/tls_config_noAuth.good.blocking.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "testdata/server.crt" 3 | key_file : "testdata/server.key" 4 | client_auth_type : "RequireAndVerifyClientCert" 5 | client_ca_file: "testdata/tls-ca-chain.pem" -------------------------------------------------------------------------------- /https/testdata/tls_config_noAuth.good.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "testdata/server.crt" 3 | key_file : "testdata/server.key" 4 | client_auth_type : "VerifyClientCertIfGiven" 5 | client_ca_file : "testdata/tls-ca-chain.pem" 6 | -------------------------------------------------------------------------------- /https/testdata/tls_config_noAuth_allCiphers.good.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "testdata/server.crt" 3 | key_file : "testdata/server.key" 4 | client_auth_type : "VerifyClientCertIfGiven" 5 | client_ca_file : "testdata/tls-ca-chain.pem" 6 | cipher_suites: 7 | - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 8 | - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 9 | - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 10 | - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 11 | - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 12 | - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 13 | - TLS_AES_128_GCM_SHA256 14 | - TLS_AES_256_GCM_SHA384 15 | - TLS_CHACHA20_POLY1305_SHA256 16 | - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 17 | - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 18 | - TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 19 | - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 20 | - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 21 | - TLS_RSA_WITH_3DES_EDE_CBC_SHA 22 | - TLS_RSA_WITH_AES_128_CBC_SHA 23 | - TLS_RSA_WITH_AES_256_CBC_SHA 24 | - TLS_RSA_WITH_AES_128_GCM_SHA256 25 | - TLS_RSA_WITH_AES_256_GCM_SHA384 26 | 27 | -------------------------------------------------------------------------------- /https/testdata/tls_config_noAuth_allCurves.good.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "testdata/server.crt" 3 | key_file : "testdata/server.key" 4 | client_auth_type : "VerifyClientCertIfGiven" 5 | client_ca_file : "testdata/tls-ca-chain.pem" 6 | curve_preferences: 7 | - CurveP256 8 | - CurveP384 9 | - CurveP521 10 | - X25519 11 | -------------------------------------------------------------------------------- /https/testdata/tls_config_noAuth_certPath_empty.bad.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "" 3 | key_file : "testdata/server.key" -------------------------------------------------------------------------------- /https/testdata/tls_config_noAuth_certPath_invalid.bad.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "somefile" 3 | key_file : "testdata/server.key" -------------------------------------------------------------------------------- /https/testdata/tls_config_noAuth_certPath_keyPath_empty.bad.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "" 3 | key_file : "" 4 | client_auth_type: "x" 5 | -------------------------------------------------------------------------------- /https/testdata/tls_config_noAuth_certPath_keyPath_invalid.bad.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "somefile" 3 | key_file : "somefile" -------------------------------------------------------------------------------- /https/testdata/tls_config_noAuth_inventedCiphers.bad.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "testdata/server.crt" 3 | key_file : "testdata/server.key" 4 | client_auth_type : "VerifyClientCertIfGiven" 5 | client_ca_file : "testdata/tls-ca-chain.pem" 6 | cipher_suites: 7 | - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA2048 8 | 9 | -------------------------------------------------------------------------------- /https/testdata/tls_config_noAuth_inventedCurves.bad.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "testdata/server.crt" 3 | key_file : "testdata/server.key" 4 | client_auth_type : "VerifyClientCertIfGiven" 5 | client_ca_file : "testdata/tls-ca-chain.pem" 6 | curve_preferences: 7 | - CurveP257 8 | -------------------------------------------------------------------------------- /https/testdata/tls_config_noAuth_keyPath_empty.bad.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "testdata/server.crt" 3 | key_file : "" -------------------------------------------------------------------------------- /https/testdata/tls_config_noAuth_keyPath_invalid.bad.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "testdata/server.cert" 3 | key_file : "somefile" -------------------------------------------------------------------------------- /https/testdata/tls_config_noAuth_noHTTP2.good.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "testdata/server.crt" 3 | key_file : "testdata/server.key" 4 | client_auth_type : "VerifyClientCertIfGiven" 5 | client_ca_file : "testdata/tls-ca-chain.pem" 6 | cipher_suites: 7 | - TLS_RSA_WITH_AES_128_CBC_SHA 8 | max_version: TLS12 9 | http_server_config: 10 | http2: false 11 | -------------------------------------------------------------------------------- /https/testdata/tls_config_noAuth_noHTTP2Cipher.bad.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "testdata/server.crt" 3 | key_file : "testdata/server.key" 4 | client_auth_type : "VerifyClientCertIfGiven" 5 | client_ca_file : "testdata/tls-ca-chain.pem" 6 | cipher_suites: 7 | - TLS_RSA_WITH_AES_128_CBC_SHA 8 | max_version: TLS12 9 | -------------------------------------------------------------------------------- /https/testdata/tls_config_noAuth_someCiphers.good.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "testdata/server.crt" 3 | key_file : "testdata/server.key" 4 | client_auth_type : "VerifyClientCertIfGiven" 5 | client_ca_file : "testdata/tls-ca-chain.pem" 6 | cipher_suites: 7 | - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 8 | - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 9 | min_version: TLS12 10 | max_version: TLS12 11 | -------------------------------------------------------------------------------- /https/testdata/tls_config_noAuth_someCiphers_noOrder.good.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "testdata/server.crt" 3 | key_file : "testdata/server.key" 4 | client_auth_type : "VerifyClientCertIfGiven" 5 | client_ca_file : "testdata/tls-ca-chain.pem" 6 | cipher_suites: 7 | - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 8 | - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 9 | prefer_server_cipher_suites: false 10 | min_version: TLS12 11 | max_version: TLS12 12 | -------------------------------------------------------------------------------- /https/testdata/tls_config_noAuth_someCurves.good.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "testdata/server.crt" 3 | key_file : "testdata/server.key" 4 | client_auth_type : "VerifyClientCertIfGiven" 5 | client_ca_file : "testdata/tls-ca-chain.pem" 6 | min_version: TLS13 7 | curve_preferences: 8 | - CurveP521 9 | -------------------------------------------------------------------------------- /https/testdata/tls_config_noAuth_wrongTLSVersion.bad.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "testdata/server.crt" 3 | key_file : "testdata/server.key" 4 | client_auth_type : "VerifyClientCertIfGiven" 5 | client_ca_file : "testdata/tls-ca-chain.pem" 6 | min_version: TLS111 7 | -------------------------------------------------------------------------------- /https/testdata/tls_config_users.good.yml: -------------------------------------------------------------------------------- 1 | tls_server_config : 2 | cert_file : "testdata/server.crt" 3 | key_file : "testdata/server.key" 4 | basic_auth_users: 5 | alice: $2y$12$1DpfPeqF9HzHJt.EWswy1exHluGfbhnn3yXhR7Xes6m3WJqFg0Wby 6 | bob: $2y$18$4VeFDzXIoPHKnKTU3O3GH.N.vZu06CVqczYZ8WvfzrddFU6tGqjR. 7 | carol: $2y$10$qRTBuFoULoYNA7AQ/F3ck.trZBPyjV64.oA4ZsSBCIWvXuvQlQTuu 8 | dave: $2y$10$2UXri9cIDdgeKjBo4Rlpx.U3ZLDV8X1IxKmsfOvhcM5oXQt/mLmXq 9 | -------------------------------------------------------------------------------- /https/testdata/tls_config_users_noTLS.good.yml: -------------------------------------------------------------------------------- 1 | basic_auth_users: 2 | alice: $2y$12$1DpfPeqF9HzHJt.EWswy1exHluGfbhnn3yXhR7Xes6m3WJqFg0Wby 3 | bob: $2y$18$4VeFDzXIoPHKnKTU3O3GH.N.vZu06CVqczYZ8WvfzrddFU6tGqjR. 4 | carol: $2y$10$qRTBuFoULoYNA7AQ/F3ck.trZBPyjV64.oA4ZsSBCIWvXuvQlQTuu 5 | dave: $2y$10$2UXri9cIDdgeKjBo4Rlpx.U3ZLDV8X1IxKmsfOvhcM5oXQt/mLmXq 6 | -------------------------------------------------------------------------------- /https/users.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Prometheus Authors 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | package https 15 | 16 | import ( 17 | "net/http" 18 | 19 | "github.com/go-kit/kit/log" 20 | "golang.org/x/crypto/bcrypt" 21 | ) 22 | 23 | func validateUsers(configPath string) error { 24 | c, err := getConfig(configPath) 25 | if err != nil { 26 | return err 27 | } 28 | 29 | for _, p := range c.Users { 30 | _, err = bcrypt.Cost([]byte(p)) 31 | if err != nil { 32 | return err 33 | } 34 | } 35 | 36 | return nil 37 | } 38 | 39 | type userAuthRoundtrip struct { 40 | tlsConfigPath string 41 | handler http.Handler 42 | logger log.Logger 43 | } 44 | 45 | func (u *userAuthRoundtrip) ServeHTTP(w http.ResponseWriter, r *http.Request) { 46 | c, err := getConfig(u.tlsConfigPath) 47 | if err != nil { 48 | u.logger.Log("msg", "Unable to parse configuration", "err", err) 49 | http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) 50 | return 51 | } 52 | 53 | if len(c.Users) == 0 { 54 | u.handler.ServeHTTP(w, r) 55 | return 56 | } 57 | 58 | user, pass, ok := r.BasicAuth() 59 | if !ok { 60 | w.Header().Set("WWW-Authenticate", "Basic") 61 | http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) 62 | return 63 | } 64 | 65 | if hashedPassword, ok := c.Users[user]; ok { 66 | if err := bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(pass)); err == nil { 67 | u.handler.ServeHTTP(w, r) 68 | return 69 | } 70 | } 71 | 72 | http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) 73 | } 74 | -------------------------------------------------------------------------------- /https/web-config.yml: -------------------------------------------------------------------------------- 1 | # Minimal TLS configuration example. Additionally, a certificate and a key file 2 | # are needed. 3 | tls_server_config: 4 | cert_file: server.crt 5 | key_file: server.key 6 | 7 | -------------------------------------------------------------------------------- /scripts/errcheck_excludes.txt: -------------------------------------------------------------------------------- 1 | // Used in HTTP handlers, any error is handled by the server itself. 2 | (net/http.ResponseWriter).Write 3 | // Never check for logger errors. 4 | (github.com/go-kit/kit/log.Logger).Log -------------------------------------------------------------------------------- /staticcheck.conf: -------------------------------------------------------------------------------- 1 | checks = ["all", "ST1003"] 2 | -------------------------------------------------------------------------------- /test_image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -exo pipefail 3 | 4 | docker_image=$1 5 | port=$2 6 | 7 | container_id='' 8 | 9 | wait_start() { 10 | for in in {1..10}; do 11 | if /usr/bin/curl -s -m 5 -f "http://localhost:${port}/metrics" > /dev/null; then 12 | docker_cleanup 13 | exit 0 14 | else 15 | sleep 1 16 | fi 17 | done 18 | 19 | exit 1 20 | } 21 | 22 | docker_start() { 23 | container_id=$(docker run -d -p "${port}":"${port}" "${docker_image}") 24 | } 25 | 26 | docker_cleanup() { 27 | docker kill "${container_id}" 28 | } 29 | 30 | if [[ "$#" -ne 2 ]] ; then 31 | echo "Usage: $0 quay.io/prometheus/node-exporter:v0.13.0 9100" >&2 32 | exit 1 33 | fi 34 | 35 | docker_start 36 | wait_start 37 | -------------------------------------------------------------------------------- /text_collector_examples/README.md: -------------------------------------------------------------------------------- 1 | # Text collector example scripts 2 | 3 | The scripts have been moved to 4 | https://github.com/prometheus-community/node-exporter-textfile-collector-scripts 5 | -------------------------------------------------------------------------------- /tls_config_noAuth.bad.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twosson/fil_exporter/260c90af3b6a6b03b19620d855c85aed5a6fcc92/tls_config_noAuth.bad.yml --------------------------------------------------------------------------------