diff options
author | Jon Davies <jpds@protonmail.com> | 2019-01-12 12:33:56 +0000 |
---|---|---|
committer | Ben Kochie <superq@gmail.com> | 2019-01-12 13:33:56 +0100 |
commit | e7664852867694265b093f79a8d8a4dcf27d0e82 (patch) | |
tree | b0addcc6a5192624834d56d5c613475fc2291fbe | |
parent | a616953b9aa996594459f0ea17e85432365582c2 (diff) | |
download | prometheus_node_collector-e7664852867694265b093f79a8d8a4dcf27d0e82.tar.bz2 prometheus_node_collector-e7664852867694265b093f79a8d8a4dcf27d0e82.tar.xz prometheus_node_collector-e7664852867694265b093f79a8d8a4dcf27d0e82.zip |
Add kstat-based Solaris metrics (#1197)
* collector/loadavg_solaris.go: Use libkstat to gather load averages.
* go.mod: Added go-kstat.
* boot_time_solaris.go: Added.
* cpu_solaris.go: Added.
* README.md: Updated entries for Solaris.
* collector/zfs_solaris.go: Added.
* CHANGELOG.md: Added note about kstat-based Solaris metrics.
Signed-off-by: Jonathan Davies <jpds@protonmail.com>
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | README.md | 6 | ||||
-rw-r--r-- | collector/boot_time_solaris.go | 66 | ||||
-rw-r--r-- | collector/cpu_solaris.go | 140 | ||||
-rw-r--r-- | collector/loadavg_solaris.go | 50 | ||||
-rw-r--r-- | collector/zfs_solaris.go | 329 | ||||
-rw-r--r-- | go.mod | 1 | ||||
-rw-r--r-- | go.sum | 2 | ||||
-rw-r--r-- | vendor/modules.txt | 2 |
9 files changed, 583 insertions, 14 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index a01241b..86d380a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md | |||
@@ -10,6 +10,7 @@ | |||
10 | * [CHANGE] Add a limit to the number of in-flight requests #1166 | 10 | * [CHANGE] Add a limit to the number of in-flight requests #1166 |
11 | * [ENHANCEMENT] Add Infiniband counters #1120 | 11 | * [ENHANCEMENT] Add Infiniband counters #1120 |
12 | * [FEATURE] Add a flag to disable exporter metrics #1148 | 12 | * [FEATURE] Add a flag to disable exporter metrics #1148 |
13 | * [FEATURE] Add kstat-based Solaris metrics for boottime, cpu and zfs collectors #1197 | ||
13 | 14 | ||
14 | ## 0.17.0 / 2018-11-30 | 15 | ## 0.17.0 / 2018-11-30 |
15 | 16 | ||
@@ -29,9 +29,9 @@ Name | Description | OS | |||
29 | arp | Exposes ARP statistics from `/proc/net/arp`. | Linux | 29 | arp | Exposes ARP statistics from `/proc/net/arp`. | Linux |
30 | bcache | Exposes bcache statistics from `/sys/fs/bcache/`. | Linux | 30 | bcache | Exposes bcache statistics from `/sys/fs/bcache/`. | Linux |
31 | bonding | Exposes the number of configured and active slaves of Linux bonding interfaces. | Linux | 31 | bonding | Exposes the number of configured and active slaves of Linux bonding interfaces. | Linux |
32 | boottime | Exposes system boot time derived from the `kern.boottime` sysctl. | Darwin, Dragonfly, FreeBSD, NetBSD, OpenBSD | 32 | boottime | Exposes system boot time derived from the `kern.boottime` sysctl. | Darwin, Dragonfly, FreeBSD, NetBSD, OpenBSD, Solaris |
33 | conntrack | Shows conntrack statistics (does nothing if no `/proc/sys/net/netfilter/` present). | Linux | 33 | conntrack | Shows conntrack statistics (does nothing if no `/proc/sys/net/netfilter/` present). | Linux |
34 | cpu | Exposes CPU statistics | Darwin, Dragonfly, FreeBSD, Linux | 34 | cpu | Exposes CPU statistics | Darwin, Dragonfly, FreeBSD, Linux, Solaris |
35 | diskstats | Exposes disk I/O statistics. | Darwin, Linux | 35 | diskstats | Exposes disk I/O statistics. | Darwin, Linux |
36 | edac | Exposes error detection and correction statistics. | Linux | 36 | edac | Exposes error detection and correction statistics. | Linux |
37 | entropy | Exposes available entropy. | Linux | 37 | entropy | Exposes available entropy. | Linux |
@@ -57,7 +57,7 @@ timex | Exposes selected adjtimex(2) system call stats. | Linux | |||
57 | uname | Exposes system information as provided by the uname system call. | Linux | 57 | uname | Exposes system information as provided by the uname system call. | Linux |
58 | vmstat | Exposes statistics from `/proc/vmstat`. | Linux | 58 | vmstat | Exposes statistics from `/proc/vmstat`. | Linux |
59 | xfs | Exposes XFS runtime statistics. | Linux (kernel 4.4+) | 59 | xfs | Exposes XFS runtime statistics. | Linux (kernel 4.4+) |
60 | zfs | Exposes [ZFS](http://open-zfs.org/) performance statistics. | [Linux](http://zfsonlinux.org/) | 60 | zfs | Exposes [ZFS](http://open-zfs.org/) performance statistics. | [Linux](http://zfsonlinux.org/), Solaris |
61 | 61 | ||
62 | ### Disabled by default | 62 | ### Disabled by default |
63 | 63 | ||
diff --git a/collector/boot_time_solaris.go b/collector/boot_time_solaris.go new file mode 100644 index 0000000..ea0c50a --- /dev/null +++ b/collector/boot_time_solaris.go | |||
@@ -0,0 +1,66 @@ | |||
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/prometheus/client_golang/prometheus" | ||
21 | "github.com/siebenmann/go-kstat" | ||
22 | ) | ||
23 | |||
24 | type bootTimeCollector struct { | ||
25 | boottime typedDesc | ||
26 | } | ||
27 | |||
28 | func init() { | ||
29 | registerCollector("boottime", defaultEnabled, newBootTimeCollector) | ||
30 | } | ||
31 | |||
32 | func newBootTimeCollector() (Collector, error) { | ||
33 | return &bootTimeCollector{ | ||
34 | boottime: typedDesc{ | ||
35 | prometheus.NewDesc( | ||
36 | prometheus.BuildFQName(namespace, "", "boot_time_seconds"), | ||
37 | "Unix time of last boot, including microseconds.", | ||
38 | nil, nil, | ||
39 | ), prometheus.GaugeValue}, | ||
40 | }, nil | ||
41 | } | ||
42 | |||
43 | // newBootTimeCollector returns a new Collector exposing system boot time on Solaris systems. | ||
44 | // Update pushes boot time onto ch | ||
45 | func (c *bootTimeCollector) Update(ch chan<- prometheus.Metric) error { | ||
46 | tok, err := kstat.Open() | ||
47 | if err != nil { | ||
48 | return err | ||
49 | } | ||
50 | |||
51 | defer tok.Close() | ||
52 | |||
53 | ks, err := tok.Lookup("unix", 0, "system_misc") | ||
54 | if err != nil { | ||
55 | return err | ||
56 | } | ||
57 | |||
58 | v, err := ks.GetNamed("boot_time") | ||
59 | if err != nil { | ||
60 | return err | ||
61 | } | ||
62 | |||
63 | ch <- c.boottime.mustNewConstMetric(float64(v.UintVal)) | ||
64 | |||
65 | return nil | ||
66 | } | ||
diff --git a/collector/cpu_solaris.go b/collector/cpu_solaris.go new file mode 100644 index 0000000..f60aeb3 --- /dev/null +++ b/collector/cpu_solaris.go | |||
@@ -0,0 +1,140 @@ | |||
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 | "fmt" | ||
21 | "strconv" | ||
22 | |||
23 | "github.com/prometheus/client_golang/prometheus" | ||
24 | "github.com/siebenmann/go-kstat" | ||
25 | ) | ||
26 | |||
27 | // #include <unistd.h> | ||
28 | import "C" | ||
29 | |||
30 | type cpuCollector struct { | ||
31 | cpu typedDesc | ||
32 | cpuFreq *prometheus.Desc | ||
33 | cpuFreqMax *prometheus.Desc | ||
34 | } | ||
35 | |||
36 | func init() { | ||
37 | registerCollector("cpu", defaultEnabled, NewCpuCollector) | ||
38 | } | ||
39 | |||
40 | func NewCpuCollector() (Collector, error) { | ||
41 | return &cpuCollector{ | ||
42 | cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue}, | ||
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 | }, nil | ||
54 | } | ||
55 | |||
56 | func (c *cpuCollector) Update(ch chan<- prometheus.Metric) error { | ||
57 | if err := c.updateCPUstats(ch); err != nil { | ||
58 | return err | ||
59 | } | ||
60 | if err := c.updateCPUfreq(ch); err != nil { | ||
61 | return err | ||
62 | } | ||
63 | return nil | ||
64 | } | ||
65 | |||
66 | func (c *cpuCollector) updateCPUstats(ch chan<- prometheus.Metric) error { | ||
67 | ncpus := C.sysconf(C._SC_NPROCESSORS_ONLN) | ||
68 | |||
69 | tok, err := kstat.Open() | ||
70 | if err != nil { | ||
71 | return err | ||
72 | } | ||
73 | |||
74 | defer tok.Close() | ||
75 | |||
76 | for cpu := 0; cpu < int(ncpus); cpu++ { | ||
77 | ksCPU, err := tok.Lookup("cpu", cpu, "sys") | ||
78 | if err != nil { | ||
79 | return err | ||
80 | } | ||
81 | |||
82 | for k, v := range map[string]string{ | ||
83 | "idle": "cpu_ticks_idle", | ||
84 | "kernel": "cpu_ticks_kernel", | ||
85 | "user": "cpu_ticks_user", | ||
86 | "wait": "cpu_ticks_wait", | ||
87 | } { | ||
88 | kstatValue, err := ksCPU.GetNamed(v) | ||
89 | if err != nil { | ||
90 | return err | ||
91 | } | ||
92 | |||
93 | ch <- c.cpu.mustNewConstMetric(float64(kstatValue.UintVal), strconv.Itoa(cpu), k) | ||
94 | } | ||
95 | } | ||
96 | return nil | ||
97 | } | ||
98 | |||
99 | func (c *cpuCollector) updateCPUfreq(ch chan<- prometheus.Metric) error { | ||
100 | ncpus := C.sysconf(C._SC_NPROCESSORS_ONLN) | ||
101 | |||
102 | tok, err := kstat.Open() | ||
103 | if err != nil { | ||
104 | return err | ||
105 | } | ||
106 | |||
107 | defer tok.Close() | ||
108 | |||
109 | for cpu := 0; cpu < int(ncpus); cpu++ { | ||
110 | ksCPUInfo, err := tok.Lookup("cpu_info", cpu, fmt.Sprintf("cpu_info%d", cpu)) | ||
111 | if err != nil { | ||
112 | return err | ||
113 | } | ||
114 | cpuFreqV, err := ksCPUInfo.GetNamed("current_clock_Hz") | ||
115 | if err != nil { | ||
116 | return err | ||
117 | } | ||
118 | |||
119 | cpuFreqMaxV, err := ksCPUInfo.GetNamed("clock_MHz") | ||
120 | if err != nil { | ||
121 | return err | ||
122 | } | ||
123 | |||
124 | lcpu := strconv.Itoa(cpu) | ||
125 | ch <- prometheus.MustNewConstMetric( | ||
126 | c.cpuFreq, | ||
127 | prometheus.GaugeValue, | ||
128 | float64(cpuFreqV.UintVal), | ||
129 | lcpu, | ||
130 | ) | ||
131 | // Multiply by 1e+6 to convert MHz to Hz. | ||
132 | ch <- prometheus.MustNewConstMetric( | ||
133 | c.cpuFreqMax, | ||
134 | prometheus.GaugeValue, | ||
135 | float64(cpuFreqMaxV.IntVal)*1e+6, | ||
136 | lcpu, | ||
137 | ) | ||
138 | } | ||
139 | return nil | ||
140 | } | ||
diff --git a/collector/loadavg_solaris.go b/collector/loadavg_solaris.go index 42ddc59..1ef8d31 100644 --- a/collector/loadavg_solaris.go +++ b/collector/loadavg_solaris.go | |||
@@ -16,21 +16,49 @@ | |||
16 | package collector | 16 | package collector |
17 | 17 | ||
18 | import ( | 18 | import ( |
19 | "errors" | 19 | "fmt" |
20 | "strconv" | ||
21 | |||
22 | "github.com/siebenmann/go-kstat" | ||
20 | ) | 23 | ) |
21 | 24 | ||
22 | /* | 25 | // #include <sys/param.h> |
23 | // Ensure "hrtime_t" is defined for sys/loadavg.h | ||
24 | #include <sys/time.h> | ||
25 | #include <sys/loadavg.h> | ||
26 | */ | ||
27 | import "C" | 26 | import "C" |
28 | 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 | |||
29 | func getLoad() ([]float64, error) { | 45 | func getLoad() ([]float64, error) { |
30 | var loadavg [3]C.double | 46 | tok, err := kstat.Open() |
31 | samples := C.getloadavg(&loadavg[0], 3) | 47 | if err != nil { |
32 | if samples != 3 { | 48 | panic(err) |
33 | return nil, errors.New("failed to get load average") | ||
34 | } | 49 | } |
35 | return []float64{float64(loadavg[0]), float64(loadavg[1]), float64(loadavg[2])}, nil | 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 | ||
36 | } | 64 | } |
diff --git a/collector/zfs_solaris.go b/collector/zfs_solaris.go new file mode 100644 index 0000000..5bf2235 --- /dev/null +++ b/collector/zfs_solaris.go | |||
@@ -0,0 +1,329 @@ | |||
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 | |||
16 | package collector | ||
17 | |||
18 | import ( | ||
19 | "strings" | ||
20 | |||
21 | "github.com/prometheus/client_golang/prometheus" | ||
22 | "github.com/siebenmann/go-kstat" | ||
23 | ) | ||
24 | |||
25 | type zfsCollector struct { | ||
26 | abdstatsLinearCount *prometheus.Desc | ||
27 | abdstatsLinearDataSize *prometheus.Desc | ||
28 | abdstatsScatterChunkWaste *prometheus.Desc | ||
29 | abdstatsScatterCount *prometheus.Desc | ||
30 | abdstatsScatterDataSize *prometheus.Desc | ||
31 | abdstatsStructSize *prometheus.Desc | ||
32 | arcstatsAnonSize *prometheus.Desc | ||
33 | arcstatsC *prometheus.Desc | ||
34 | arcstatsCMax *prometheus.Desc | ||
35 | arcstatsCMin *prometheus.Desc | ||
36 | arcstatsDataSize *prometheus.Desc | ||
37 | arcstatsDemandDataHits *prometheus.Desc | ||
38 | arcstatsDemandDataMisses *prometheus.Desc | ||
39 | arcstatsDemandMetadataHits *prometheus.Desc | ||
40 | arcstatsDemandMetadataMisses *prometheus.Desc | ||
41 | arcstatsHeaderSize *prometheus.Desc | ||
42 | arcstatsHits *prometheus.Desc | ||
43 | arcstatsMisses *prometheus.Desc | ||
44 | arcstatsMFUGhostHits *prometheus.Desc | ||
45 | arcstatsMFUGhostSize *prometheus.Desc | ||
46 | arcstatsMFUSize *prometheus.Desc | ||
47 | arcstatsMRUGhostHits *prometheus.Desc | ||
48 | arcstatsMRUGhostSize *prometheus.Desc | ||
49 | arcstatsMRUSize *prometheus.Desc | ||
50 | arcstatsOtherSize *prometheus.Desc | ||
51 | arcstatsP *prometheus.Desc | ||
52 | arcstatsSize *prometheus.Desc | ||
53 | zfetchstatsHits *prometheus.Desc | ||
54 | zfetchstatsMisses *prometheus.Desc | ||
55 | } | ||
56 | |||
57 | const ( | ||
58 | zfsCollectorSubsystem = "zfs" | ||
59 | ) | ||
60 | |||
61 | func init() { | ||
62 | registerCollector("zfs", defaultEnabled, NewZfsCollector) | ||
63 | } | ||
64 | |||
65 | func NewZfsCollector() (Collector, error) { | ||
66 | return &zfsCollector{ | ||
67 | abdstatsLinearCount: prometheus.NewDesc( | ||
68 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "abdstats_linear_count_total"), | ||
69 | "ZFS ARC buffer data linear count", nil, nil, | ||
70 | ), | ||
71 | abdstatsLinearDataSize: prometheus.NewDesc( | ||
72 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "abdstats_linear_data_bytes"), | ||
73 | "ZFS ARC buffer data linear data size", nil, nil, | ||
74 | ), | ||
75 | abdstatsScatterChunkWaste: prometheus.NewDesc( | ||
76 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "abdstats_scatter_chunk_waste_bytes"), | ||
77 | "ZFS ARC buffer data scatter chunk waste", nil, nil, | ||
78 | ), | ||
79 | abdstatsScatterCount: prometheus.NewDesc( | ||
80 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "abdstats_scatter_count_total"), | ||
81 | "ZFS ARC buffer data scatter count", nil, nil, | ||
82 | ), | ||
83 | abdstatsScatterDataSize: prometheus.NewDesc( | ||
84 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "abdstats_scatter_data_bytes"), | ||
85 | "ZFS ARC buffer data scatter data size", nil, nil, | ||
86 | ), | ||
87 | abdstatsStructSize: prometheus.NewDesc( | ||
88 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "abdstats_struct_bytes"), | ||
89 | "ZFS ARC buffer data struct size", nil, nil, | ||
90 | ), | ||
91 | arcstatsAnonSize: prometheus.NewDesc( | ||
92 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_anon_bytes"), | ||
93 | "ZFS ARC anon size", nil, nil, | ||
94 | ), | ||
95 | arcstatsC: prometheus.NewDesc( | ||
96 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_c_bytes"), | ||
97 | "ZFS ARC target size", nil, nil, | ||
98 | ), | ||
99 | arcstatsCMax: prometheus.NewDesc( | ||
100 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_c_max_bytes"), | ||
101 | "ZFS ARC maximum size", nil, nil, | ||
102 | ), | ||
103 | arcstatsCMin: prometheus.NewDesc( | ||
104 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_c_min_bytes"), | ||
105 | "ZFS ARC minimum size", nil, nil, | ||
106 | ), | ||
107 | arcstatsDataSize: prometheus.NewDesc( | ||
108 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_data_bytes"), | ||
109 | "ZFS ARC data size", nil, nil, | ||
110 | ), | ||
111 | arcstatsDemandDataHits: prometheus.NewDesc( | ||
112 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_demand_data_hits_total"), | ||
113 | "ZFS ARC demand data hits", nil, nil, | ||
114 | ), | ||
115 | arcstatsDemandDataMisses: prometheus.NewDesc( | ||
116 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_demand_data_misses_total"), | ||
117 | "ZFS ARC demand data misses", nil, nil, | ||
118 | ), | ||
119 | arcstatsDemandMetadataHits: prometheus.NewDesc( | ||
120 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_demand_metadata_hits_total"), | ||
121 | "ZFS ARC demand metadata hits", nil, nil, | ||
122 | ), | ||
123 | arcstatsDemandMetadataMisses: prometheus.NewDesc( | ||
124 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_demand_metadata_misses_total"), | ||
125 | "ZFS ARC demand metadata misses", nil, nil, | ||
126 | ), | ||
127 | arcstatsHeaderSize: prometheus.NewDesc( | ||
128 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_hdr_bytes"), | ||
129 | "ZFS ARC header size", nil, nil, | ||
130 | ), | ||
131 | arcstatsHits: prometheus.NewDesc( | ||
132 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_hits_total"), | ||
133 | "ZFS ARC hits", nil, nil, | ||
134 | ), | ||
135 | arcstatsMisses: prometheus.NewDesc( | ||
136 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_misses_total"), | ||
137 | "ZFS ARC misses", nil, nil, | ||
138 | ), | ||
139 | arcstatsMFUGhostHits: prometheus.NewDesc( | ||
140 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_mfu_ghost_hits_total"), | ||
141 | "ZFS ARC MFU ghost hits", nil, nil, | ||
142 | ), | ||
143 | arcstatsMFUGhostSize: prometheus.NewDesc( | ||
144 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_mfu_ghost_size"), | ||
145 | "ZFS ARC MFU ghost size", nil, nil, | ||
146 | ), | ||
147 | arcstatsMFUSize: prometheus.NewDesc( | ||
148 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_mfu_bytes"), | ||
149 | "ZFS ARC MFU size", nil, nil, | ||
150 | ), | ||
151 | arcstatsMRUGhostHits: prometheus.NewDesc( | ||
152 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_mru_ghost_hits_total"), | ||
153 | "ZFS ARC MRU ghost hits", nil, nil, | ||
154 | ), | ||
155 | arcstatsMRUGhostSize: prometheus.NewDesc( | ||
156 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_mru_ghost_bytes"), | ||
157 | "ZFS ARC MRU ghost size", nil, nil, | ||
158 | ), | ||
159 | arcstatsMRUSize: prometheus.NewDesc( | ||
160 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_mru_bytes"), | ||
161 | "ZFS ARC MRU size", nil, nil, | ||
162 | ), | ||
163 | arcstatsOtherSize: prometheus.NewDesc( | ||
164 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_other_bytes"), | ||
165 | "ZFS ARC other size", nil, nil, | ||
166 | ), | ||
167 | arcstatsP: prometheus.NewDesc( | ||
168 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_p_bytes"), | ||
169 | "ZFS ARC MRU target size", nil, nil, | ||
170 | ), | ||
171 | arcstatsSize: prometheus.NewDesc( | ||
172 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "arcstats_size_bytes"), | ||
173 | "ZFS ARC size", nil, nil, | ||
174 | ), | ||
175 | zfetchstatsHits: prometheus.NewDesc( | ||
176 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "zfetchstats_hits_total"), | ||
177 | "ZFS cache fetch hits", nil, nil, | ||
178 | ), | ||
179 | zfetchstatsMisses: prometheus.NewDesc( | ||
180 | prometheus.BuildFQName(namespace, zfsCollectorSubsystem, "zfetchstats_misses_total"), | ||
181 | "ZFS cache fetch misses", nil, nil, | ||
182 | ), | ||
183 | }, nil | ||
184 | } | ||
185 | |||
186 | func (c *zfsCollector) updateZfsAbdStats(ch chan<- prometheus.Metric) error { | ||
187 | var metricType prometheus.ValueType | ||
188 | |||
189 | tok, err := kstat.Open() | ||
190 | if err != nil { | ||
191 | return err | ||
192 | } | ||
193 | |||
194 | defer tok.Close() | ||
195 | |||
196 | ksZFSInfo, err := tok.Lookup("zfs", 0, "abdstats") | ||
197 | if err != nil { | ||
198 | return err | ||
199 | } | ||
200 | |||
201 | for k, v := range map[string]*prometheus.Desc{ | ||
202 | "linear_cnt": c.abdstatsLinearCount, | ||
203 | "linear_data_size": c.abdstatsLinearDataSize, | ||
204 | "scatter_chunk_waste": c.abdstatsScatterChunkWaste, | ||
205 | "scatter_cnt": c.abdstatsScatterCount, | ||
206 | "scatter_data_size": c.abdstatsScatterDataSize, | ||
207 | "struct_size": c.abdstatsStructSize, | ||
208 | } { | ||
209 | ksZFSInfoValue, err := ksZFSInfo.GetNamed(k) | ||
210 | if err != nil { | ||
211 | return err | ||
212 | } | ||
213 | |||
214 | if strings.HasSuffix(k, "_cnt") { | ||
215 | metricType = prometheus.CounterValue | ||
216 | } else { | ||
217 | metricType = prometheus.GaugeValue | ||
218 | } | ||
219 | |||
220 | ch <- prometheus.MustNewConstMetric( | ||
221 | v, | ||
222 | metricType, | ||
223 | float64(ksZFSInfoValue.UintVal), | ||
224 | ) | ||
225 | } | ||
226 | |||
227 | return nil | ||
228 | } | ||
229 | |||
230 | func (c *zfsCollector) updateZfsArcStats(ch chan<- prometheus.Metric) error { | ||
231 | var metricType prometheus.ValueType | ||
232 | |||
233 | tok, err := kstat.Open() | ||
234 | if err != nil { | ||
235 | return err | ||
236 | } | ||
237 | |||
238 | defer tok.Close() | ||
239 | |||
240 | ksZFSInfo, err := tok.Lookup("zfs", 0, "arcstats") | ||
241 | if err != nil { | ||
242 | return err | ||
243 | } | ||
244 | |||
245 | for k, v := range map[string]*prometheus.Desc{ | ||
246 | "anon_size": c.arcstatsAnonSize, | ||
247 | "c": c.arcstatsC, | ||
248 | "c_max": c.arcstatsCMax, | ||
249 | "c_min": c.arcstatsCMin, | ||
250 | "data_size": c.arcstatsDataSize, | ||
251 | "demand_data_hits": c.arcstatsDemandDataHits, | ||
252 | "demand_data_misses": c.arcstatsDemandDataMisses, | ||
253 | "demand_metadata_hits": c.arcstatsDemandMetadataHits, | ||
254 | "demand_metadata_misses": c.arcstatsDemandMetadataMisses, | ||
255 | "hdr_size": c.arcstatsHeaderSize, | ||
256 | "hits": c.arcstatsHits, | ||
257 | "misses": c.arcstatsMisses, | ||
258 | "mfu_ghost_hits": c.arcstatsMFUGhostHits, | ||
259 | "mfu_ghost_size": c.arcstatsMFUGhostSize, | ||
260 | "mfu_size": c.arcstatsMFUSize, | ||
261 | "mru_ghost_hits": c.arcstatsMRUGhostHits, | ||
262 | "mru_ghost_size": c.arcstatsMRUGhostSize, | ||
263 | "mru_size": c.arcstatsMRUSize, | ||
264 | "other_size": c.arcstatsOtherSize, | ||
265 | "p": c.arcstatsP, | ||
266 | "size": c.arcstatsSize, | ||
267 | } { | ||
268 | ksZFSInfoValue, err := ksZFSInfo.GetNamed(k) | ||
269 | if err != nil { | ||
270 | return err | ||
271 | } | ||
272 | |||
273 | if strings.HasSuffix(k, "_hits") || strings.HasSuffix(k, "_misses") { | ||
274 | metricType = prometheus.CounterValue | ||
275 | } else { | ||
276 | metricType = prometheus.GaugeValue | ||
277 | } | ||
278 | |||
279 | ch <- prometheus.MustNewConstMetric( | ||
280 | v, | ||
281 | metricType, | ||
282 | float64(ksZFSInfoValue.UintVal), | ||
283 | ) | ||
284 | } | ||
285 | |||
286 | return nil | ||
287 | } | ||
288 | |||
289 | func (c *zfsCollector) updateZfsFetchStats(ch chan<- prometheus.Metric) error { | ||
290 | tok, err := kstat.Open() | ||
291 | if err != nil { | ||
292 | return err | ||
293 | } | ||
294 | |||
295 | defer tok.Close() | ||
296 | |||
297 | ksZFSInfo, err := tok.Lookup("zfs", 0, "zfetchstats") | ||
298 | |||
299 | for k, v := range map[string]*prometheus.Desc{ | ||
300 | "hits": c.zfetchstatsHits, | ||
301 | "misses": c.zfetchstatsMisses, | ||
302 | } { | ||
303 | ksZFSInfoValue, err := ksZFSInfo.GetNamed(k) | ||
304 | if err != nil { | ||
305 | return err | ||
306 | } | ||
307 | |||
308 | ch <- prometheus.MustNewConstMetric( | ||
309 | v, | ||
310 | prometheus.CounterValue, | ||
311 | float64(ksZFSInfoValue.UintVal), | ||
312 | ) | ||
313 | } | ||
314 | |||
315 | return nil | ||
316 | } | ||
317 | |||
318 | func (c *zfsCollector) Update(ch chan<- prometheus.Metric) error { | ||
319 | if err := c.updateZfsAbdStats(ch); err != nil { | ||
320 | return err | ||
321 | } | ||
322 | if err := c.updateZfsArcStats(ch); err != nil { | ||
323 | return err | ||
324 | } | ||
325 | if err := c.updateZfsFetchStats(ch); err != nil { | ||
326 | return err | ||
327 | } | ||
328 | return nil | ||
329 | } | ||
@@ -22,6 +22,7 @@ require ( | |||
22 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 | 22 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 |
23 | github.com/prometheus/common v0.0.0-20181015124227-bcb74de08d37 | 23 | github.com/prometheus/common v0.0.0-20181015124227-bcb74de08d37 |
24 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d | 24 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d |
25 | github.com/siebenmann/go-kstat v0.0.0-20160321171754-d34789b79745 | ||
25 | github.com/sirupsen/logrus v1.1.1 // indirect | 26 | github.com/sirupsen/logrus v1.1.1 // indirect |
26 | github.com/soundcloud/go-runit v0.0.0-20150630195641-06ad41a06c4a | 27 | github.com/soundcloud/go-runit v0.0.0-20150630195641-06ad41a06c4a |
27 | golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941 // indirect | 28 | golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941 // indirect |
@@ -45,6 +45,8 @@ github.com/prometheus/common v0.0.0-20181015124227-bcb74de08d37 h1:Y7YdJ9Xb3MoQO | |||
45 | github.com/prometheus/common v0.0.0-20181015124227-bcb74de08d37/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= | 45 | github.com/prometheus/common v0.0.0-20181015124227-bcb74de08d37/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= |
46 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d h1:GoAlyOgbOEIFdaDqxJVlbOQ1DtGmZWs/Qau0hIlk+WQ= | 46 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d h1:GoAlyOgbOEIFdaDqxJVlbOQ1DtGmZWs/Qau0hIlk+WQ= |
47 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= | 47 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= |
48 | github.com/siebenmann/go-kstat v0.0.0-20160321171754-d34789b79745 h1:IuH7WumZNax0D+rEqmy2TyhKCzrtMGqbZO0b8rO00JA= | ||
49 | github.com/siebenmann/go-kstat v0.0.0-20160321171754-d34789b79745/go.mod h1:G81aIFAMS9ECrwBYR9YxhlPjWgrItd+Kje78O6+uqm8= | ||
48 | github.com/sirupsen/logrus v1.1.1 h1:VzGj7lhU7KEB9e9gMpAV/v5XT2NVSvLJhJLCWbnkgXg= | 50 | github.com/sirupsen/logrus v1.1.1 h1:VzGj7lhU7KEB9e9gMpAV/v5XT2NVSvLJhJLCWbnkgXg= |
49 | github.com/sirupsen/logrus v1.1.1/go.mod h1:zrgwTnHtNr00buQ1vSptGe8m1f/BbgsPukg8qsT7A+A= | 51 | github.com/sirupsen/logrus v1.1.1/go.mod h1:zrgwTnHtNr00buQ1vSptGe8m1f/BbgsPukg8qsT7A+A= |
50 | github.com/soundcloud/go-runit v0.0.0-20150630195641-06ad41a06c4a h1:os5OBNhwOwybXZMNLqT96XqtjdTtwRFw2w08uluvNeI= | 52 | github.com/soundcloud/go-runit v0.0.0-20150630195641-06ad41a06c4a h1:os5OBNhwOwybXZMNLqT96XqtjdTtwRFw2w08uluvNeI= |
diff --git a/vendor/modules.txt b/vendor/modules.txt index d048101..dbd7d5f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt | |||
@@ -50,6 +50,8 @@ github.com/prometheus/procfs/nfs | |||
50 | github.com/prometheus/procfs/sysfs | 50 | github.com/prometheus/procfs/sysfs |
51 | github.com/prometheus/procfs/xfs | 51 | github.com/prometheus/procfs/xfs |
52 | github.com/prometheus/procfs/internal/util | 52 | github.com/prometheus/procfs/internal/util |
53 | # github.com/siebenmann/go-kstat v0.0.0-20160321171754-d34789b79745 | ||
54 | github.com/siebenmann/go-kstat | ||
53 | # github.com/sirupsen/logrus v1.1.1 | 55 | # github.com/sirupsen/logrus v1.1.1 |
54 | github.com/sirupsen/logrus | 56 | github.com/sirupsen/logrus |
55 | # github.com/soundcloud/go-runit v0.0.0-20150630195641-06ad41a06c4a | 57 | # github.com/soundcloud/go-runit v0.0.0-20150630195641-06ad41a06c4a |