diff options
author | Ralf Horstmann <ralf+github@ackstorm.de> | 2019-02-06 11:36:22 +0100 |
---|---|---|
committer | Ben Kochie <superq@gmail.com> | 2019-02-06 11:36:22 +0100 |
commit | 3867ad5ab00846010238bc10ab6aec04169fd7f5 (patch) | |
tree | 0a79e820e80c484069a6abbe21b57743bd48c9ea | |
parent | d442108d7ae3c3445b501fd253816b40c322a4f9 (diff) | |
download | prometheus_node_collector-3867ad5ab00846010238bc10ab6aec04169fd7f5.tar.bz2 prometheus_node_collector-3867ad5ab00846010238bc10ab6aec04169fd7f5.tar.xz prometheus_node_collector-3867ad5ab00846010238bc10ab6aec04169fd7f5.zip |
Add diskstats collector for OpenBSD (#1250)
* Add diskstats collector for OpenBSD
Tested on i386 and amd64, OpenBSD 6.4 and -current.
* Refactor diskstats collectors
This moves common descriptors from Linux, Darwin, OpenBSD
diskstats collectors into diskstats_common.go
Signed-off-by: Ralf Horstmann <ralf+github@ackstorm.de>
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | collector/diskstats_common.go | 73 | ||||
-rw-r--r-- | collector/diskstats_darwin.go | 46 | ||||
-rw-r--r-- | collector/diskstats_linux.go | 50 | ||||
-rw-r--r-- | collector/diskstats_openbsd.go | 74 |
6 files changed, 162 insertions, 84 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index c445503..b3c464d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md | |||
@@ -15,6 +15,7 @@ The cpufreq metrics now separate the `cpufreq` and `scaling` data based on what | |||
15 | * [FEATURE] Add a flag to disable exporter metrics #1148 | 15 | * [FEATURE] Add a flag to disable exporter metrics #1148 |
16 | * [FEATURE] Add kstat-based Solaris metrics for boottime, cpu and zfs collectors #1197 | 16 | * [FEATURE] Add kstat-based Solaris metrics for boottime, cpu and zfs collectors #1197 |
17 | * [FEATURE] Add uname collector for FreeBSD #1239 | 17 | * [FEATURE] Add uname collector for FreeBSD #1239 |
18 | * [FEATURE] Add diskstats collector for OpenBSD #1250 | ||
18 | 19 | ||
19 | ## 0.17.0 / 2018-11-30 | 20 | ## 0.17.0 / 2018-11-30 |
20 | 21 | ||
@@ -32,7 +32,7 @@ bonding | Exposes the number of configured and active slaves of Linux bonding in | |||
32 | boottime | Exposes system boot time derived from the `kern.boottime` sysctl. | Darwin, Dragonfly, FreeBSD, NetBSD, OpenBSD, Solaris | 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, Solaris | 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, OpenBSD |
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 |
38 | exec | Exposes execution statistics. | Dragonfly, FreeBSD | 38 | exec | Exposes execution statistics. | Dragonfly, FreeBSD |
diff --git a/collector/diskstats_common.go b/collector/diskstats_common.go new file mode 100644 index 0000000..7efb399 --- /dev/null +++ b/collector/diskstats_common.go | |||
@@ -0,0 +1,73 @@ | |||
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 | ) | ||
diff --git a/collector/diskstats_darwin.go b/collector/diskstats_darwin.go index a92de52..2c76582 100644 --- a/collector/diskstats_darwin.go +++ b/collector/diskstats_darwin.go | |||
@@ -22,10 +22,6 @@ import ( | |||
22 | "github.com/prometheus/client_golang/prometheus" | 22 | "github.com/prometheus/client_golang/prometheus" |
23 | ) | 23 | ) |
24 | 24 | ||
25 | const ( | ||
26 | diskSubsystem = "disk" | ||
27 | ) | ||
28 | |||
29 | type typedDescFunc struct { | 25 | type typedDescFunc struct { |
30 | typedDesc | 26 | typedDesc |
31 | value func(stat *iostat.DriveStats) float64 | 27 | value func(stat *iostat.DriveStats) float64 |
@@ -47,12 +43,7 @@ func NewDiskstatsCollector() (Collector, error) { | |||
47 | descs: []typedDescFunc{ | 43 | descs: []typedDescFunc{ |
48 | { | 44 | { |
49 | typedDesc: typedDesc{ | 45 | typedDesc: typedDesc{ |
50 | desc: prometheus.NewDesc( | 46 | desc: readsCompletedDesc, |
51 | prometheus.BuildFQName(namespace, diskSubsystem, "reads_completed_total"), | ||
52 | "The total number of reads completed successfully.", | ||
53 | diskLabelNames, | ||
54 | nil, | ||
55 | ), | ||
56 | valueType: prometheus.CounterValue, | 47 | valueType: prometheus.CounterValue, |
57 | }, | 48 | }, |
58 | value: func(stat *iostat.DriveStats) float64 { | 49 | value: func(stat *iostat.DriveStats) float64 { |
@@ -75,12 +66,7 @@ func NewDiskstatsCollector() (Collector, error) { | |||
75 | }, | 66 | }, |
76 | { | 67 | { |
77 | typedDesc: typedDesc{ | 68 | typedDesc: typedDesc{ |
78 | desc: prometheus.NewDesc( | 69 | desc: readTimeSecondsDesc, |
79 | prometheus.BuildFQName(namespace, diskSubsystem, "read_time_seconds_total"), | ||
80 | "The total number of seconds spent by all reads.", | ||
81 | diskLabelNames, | ||
82 | nil, | ||
83 | ), | ||
84 | valueType: prometheus.CounterValue, | 70 | valueType: prometheus.CounterValue, |
85 | }, | 71 | }, |
86 | value: func(stat *iostat.DriveStats) float64 { | 72 | value: func(stat *iostat.DriveStats) float64 { |
@@ -89,12 +75,7 @@ func NewDiskstatsCollector() (Collector, error) { | |||
89 | }, | 75 | }, |
90 | { | 76 | { |
91 | typedDesc: typedDesc{ | 77 | typedDesc: typedDesc{ |
92 | desc: prometheus.NewDesc( | 78 | desc: writesCompletedDesc, |
93 | prometheus.BuildFQName(namespace, diskSubsystem, "writes_completed_total"), | ||
94 | "The total number of writes completed successfully.", | ||
95 | diskLabelNames, | ||
96 | nil, | ||
97 | ), | ||
98 | valueType: prometheus.CounterValue, | 79 | valueType: prometheus.CounterValue, |
99 | }, | 80 | }, |
100 | value: func(stat *iostat.DriveStats) float64 { | 81 | value: func(stat *iostat.DriveStats) float64 { |
@@ -117,12 +98,7 @@ func NewDiskstatsCollector() (Collector, error) { | |||
117 | }, | 98 | }, |
118 | { | 99 | { |
119 | typedDesc: typedDesc{ | 100 | typedDesc: typedDesc{ |
120 | desc: prometheus.NewDesc( | 101 | desc: writeTimeSecondsDesc, |
121 | prometheus.BuildFQName(namespace, diskSubsystem, "write_time_seconds_total"), | ||
122 | "This is the total number of seconds spent by all writes.", | ||
123 | diskLabelNames, | ||
124 | nil, | ||
125 | ), | ||
126 | valueType: prometheus.CounterValue, | 102 | valueType: prometheus.CounterValue, |
127 | }, | 103 | }, |
128 | value: func(stat *iostat.DriveStats) float64 { | 104 | value: func(stat *iostat.DriveStats) float64 { |
@@ -131,12 +107,7 @@ func NewDiskstatsCollector() (Collector, error) { | |||
131 | }, | 107 | }, |
132 | { | 108 | { |
133 | typedDesc: typedDesc{ | 109 | typedDesc: typedDesc{ |
134 | desc: prometheus.NewDesc( | 110 | desc: readBytesDesc, |
135 | prometheus.BuildFQName(namespace, diskSubsystem, "read_bytes_total"), | ||
136 | "The total number of bytes read successfully.", | ||
137 | diskLabelNames, | ||
138 | nil, | ||
139 | ), | ||
140 | valueType: prometheus.CounterValue, | 111 | valueType: prometheus.CounterValue, |
141 | }, | 112 | }, |
142 | value: func(stat *iostat.DriveStats) float64 { | 113 | value: func(stat *iostat.DriveStats) float64 { |
@@ -145,12 +116,7 @@ func NewDiskstatsCollector() (Collector, error) { | |||
145 | }, | 116 | }, |
146 | { | 117 | { |
147 | typedDesc: typedDesc{ | 118 | typedDesc: typedDesc{ |
148 | desc: prometheus.NewDesc( | 119 | desc: writtenBytesDesc, |
149 | prometheus.BuildFQName(namespace, diskSubsystem, "written_bytes_total"), | ||
150 | "The total number of bytes written successfully.", | ||
151 | diskLabelNames, | ||
152 | nil, | ||
153 | ), | ||
154 | valueType: prometheus.CounterValue, | 120 | valueType: prometheus.CounterValue, |
155 | }, | 121 | }, |
156 | value: func(stat *iostat.DriveStats) float64 { | 122 | value: func(stat *iostat.DriveStats) float64 { |
diff --git a/collector/diskstats_linux.go b/collector/diskstats_linux.go index 8efffd9..1d39f2b 100644 --- a/collector/diskstats_linux.go +++ b/collector/diskstats_linux.go | |||
@@ -30,7 +30,6 @@ import ( | |||
30 | ) | 30 | ) |
31 | 31 | ||
32 | const ( | 32 | const ( |
33 | diskSubsystem = "disk" | ||
34 | diskSectorSize = 512 | 33 | diskSectorSize = 512 |
35 | diskstatsFilename = "diskstats" | 34 | diskstatsFilename = "diskstats" |
36 | ) | 35 | ) |
@@ -70,12 +69,7 @@ func NewDiskstatsCollector() (Collector, error) { | |||
70 | ignoredDevicesPattern: regexp.MustCompile(*ignoredDevices), | 69 | ignoredDevicesPattern: regexp.MustCompile(*ignoredDevices), |
71 | descs: []typedFactorDesc{ | 70 | descs: []typedFactorDesc{ |
72 | { | 71 | { |
73 | desc: prometheus.NewDesc( | 72 | desc: readsCompletedDesc, valueType: prometheus.CounterValue, |
74 | prometheus.BuildFQName(namespace, diskSubsystem, "reads_completed_total"), | ||
75 | "The total number of reads completed successfully.", | ||
76 | diskLabelNames, | ||
77 | nil, | ||
78 | ), valueType: prometheus.CounterValue, | ||
79 | }, | 73 | }, |
80 | { | 74 | { |
81 | desc: prometheus.NewDesc( | 75 | desc: prometheus.NewDesc( |
@@ -86,30 +80,15 @@ func NewDiskstatsCollector() (Collector, error) { | |||
86 | ), valueType: prometheus.CounterValue, | 80 | ), valueType: prometheus.CounterValue, |
87 | }, | 81 | }, |
88 | { | 82 | { |
89 | desc: prometheus.NewDesc( | 83 | desc: readBytesDesc, valueType: prometheus.CounterValue, |
90 | prometheus.BuildFQName(namespace, diskSubsystem, "read_bytes_total"), | ||
91 | "The total number of bytes read successfully.", | ||
92 | diskLabelNames, | ||
93 | nil, | ||
94 | ), valueType: prometheus.CounterValue, | ||
95 | factor: diskSectorSize, | 84 | factor: diskSectorSize, |
96 | }, | 85 | }, |
97 | { | 86 | { |
98 | desc: prometheus.NewDesc( | 87 | desc: readTimeSecondsDesc, valueType: prometheus.CounterValue, |
99 | prometheus.BuildFQName(namespace, diskSubsystem, "read_time_seconds_total"), | ||
100 | "The total number of seconds spent by all reads.", | ||
101 | diskLabelNames, | ||
102 | nil, | ||
103 | ), valueType: prometheus.CounterValue, | ||
104 | factor: .001, | 88 | factor: .001, |
105 | }, | 89 | }, |
106 | { | 90 | { |
107 | desc: prometheus.NewDesc( | 91 | desc: writesCompletedDesc, valueType: prometheus.CounterValue, |
108 | prometheus.BuildFQName(namespace, diskSubsystem, "writes_completed_total"), | ||
109 | "The total number of writes completed successfully.", | ||
110 | diskLabelNames, | ||
111 | nil, | ||
112 | ), valueType: prometheus.CounterValue, | ||
113 | }, | 92 | }, |
114 | { | 93 | { |
115 | desc: prometheus.NewDesc( | 94 | desc: prometheus.NewDesc( |
@@ -120,21 +99,11 @@ func NewDiskstatsCollector() (Collector, error) { | |||
120 | ), valueType: prometheus.CounterValue, | 99 | ), valueType: prometheus.CounterValue, |
121 | }, | 100 | }, |
122 | { | 101 | { |
123 | desc: prometheus.NewDesc( | 102 | desc: writtenBytesDesc, valueType: prometheus.CounterValue, |
124 | prometheus.BuildFQName(namespace, diskSubsystem, "written_bytes_total"), | ||
125 | "The total number of bytes written successfully.", | ||
126 | diskLabelNames, | ||
127 | nil, | ||
128 | ), valueType: prometheus.CounterValue, | ||
129 | factor: diskSectorSize, | 103 | factor: diskSectorSize, |
130 | }, | 104 | }, |
131 | { | 105 | { |
132 | desc: prometheus.NewDesc( | 106 | desc: writeTimeSecondsDesc, valueType: prometheus.CounterValue, |
133 | prometheus.BuildFQName(namespace, diskSubsystem, "write_time_seconds_total"), | ||
134 | "This is the total number of seconds spent by all writes.", | ||
135 | diskLabelNames, | ||
136 | nil, | ||
137 | ), valueType: prometheus.CounterValue, | ||
138 | factor: .001, | 107 | factor: .001, |
139 | }, | 108 | }, |
140 | { | 109 | { |
@@ -146,12 +115,7 @@ func NewDiskstatsCollector() (Collector, error) { | |||
146 | ), valueType: prometheus.GaugeValue, | 115 | ), valueType: prometheus.GaugeValue, |
147 | }, | 116 | }, |
148 | { | 117 | { |
149 | desc: prometheus.NewDesc( | 118 | desc: ioTimeSecondsDesc, valueType: prometheus.CounterValue, |
150 | prometheus.BuildFQName(namespace, diskSubsystem, "io_time_seconds_total"), | ||
151 | "Total seconds spent doing I/Os.", | ||
152 | diskLabelNames, | ||
153 | nil, | ||
154 | ), valueType: prometheus.CounterValue, | ||
155 | factor: .001, | 119 | factor: .001, |
156 | }, | 120 | }, |
157 | { | 121 | { |
diff --git a/collector/diskstats_openbsd.go b/collector/diskstats_openbsd.go new file mode 100644 index 0000000..f17e2a8 --- /dev/null +++ b/collector/diskstats_openbsd.go | |||
@@ -0,0 +1,74 @@ | |||
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/prometheus/client_golang/prometheus" | ||
22 | "golang.org/x/sys/unix" | ||
23 | ) | ||
24 | |||
25 | /* | ||
26 | #include <sys/types.h> | ||
27 | #include <sys/disk.h> | ||
28 | */ | ||
29 | import "C" | ||
30 | |||
31 | type diskstatsCollector struct { | ||
32 | rxfer typedDesc | ||
33 | rbytes typedDesc | ||
34 | wxfer typedDesc | ||
35 | wbytes typedDesc | ||
36 | time typedDesc | ||
37 | } | ||
38 | |||
39 | func init() { | ||
40 | registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector) | ||
41 | } | ||
42 | |||
43 | // NewDiskstatsCollector returns a new Collector exposing disk device stats. | ||
44 | func NewDiskstatsCollector() (Collector, error) { | ||
45 | return &diskstatsCollector{ | ||
46 | rxfer: typedDesc{readsCompletedDesc, prometheus.CounterValue}, | ||
47 | rbytes: typedDesc{readBytesDesc, prometheus.CounterValue}, | ||
48 | wxfer: typedDesc{writesCompletedDesc, prometheus.CounterValue}, | ||
49 | wbytes: typedDesc{writtenBytesDesc, prometheus.CounterValue}, | ||
50 | time: typedDesc{ioTimeSecondsDesc, prometheus.CounterValue}, | ||
51 | }, nil | ||
52 | } | ||
53 | |||
54 | func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) (err error) { | ||
55 | diskstatsb, err := unix.SysctlRaw("hw.diskstats") | ||
56 | if err != nil { | ||
57 | return err | ||
58 | } | ||
59 | |||
60 | ndisks := len(diskstatsb) / C.sizeof_struct_diskstats | ||
61 | diskstats := *(*[]C.struct_diskstats)(unsafe.Pointer(&diskstatsb)) | ||
62 | |||
63 | for i := 0; i < ndisks; i++ { | ||
64 | diskname := C.GoString(&diskstats[i].ds_name[0]) | ||
65 | |||
66 | ch <- c.rxfer.mustNewConstMetric(float64(diskstats[i].ds_rxfer), diskname) | ||
67 | ch <- c.rbytes.mustNewConstMetric(float64(diskstats[i].ds_rbytes), diskname) | ||
68 | ch <- c.wxfer.mustNewConstMetric(float64(diskstats[i].ds_wxfer), diskname) | ||
69 | ch <- c.wbytes.mustNewConstMetric(float64(diskstats[i].ds_wbytes), diskname) | ||
70 | time := float64(diskstats[i].ds_time.tv_sec) + float64(diskstats[i].ds_time.tv_usec)/1000000 | ||
71 | ch <- c.time.mustNewConstMetric(time, diskname) | ||
72 | } | ||
73 | return nil | ||
74 | } | ||