fluent-plugin-node-exporter-metrics 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/linux-test.yaml +42 -0
- data/.gitignore +2 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile +3 -0
- data/LICENSE +202 -0
- data/README.md +167 -0
- data/Rakefile +13 -0
- data/docs/cpu.md +26 -0
- data/docs/cpufreq.md +43 -0
- data/docs/diskstats.md +27 -0
- data/docs/filefd.md +12 -0
- data/docs/loadavg.md +13 -0
- data/docs/meminfo.md +61 -0
- data/docs/netdev.md +26 -0
- data/docs/stat.md +17 -0
- data/docs/time.md +9 -0
- data/docs/uname.md +15 -0
- data/docs/vmstat.md +17 -0
- data/fluent-plugin-node-exporter-metrics.gemspec +31 -0
- data/lib/fluent/plugin/in_node_exporter_metrics.rb +138 -0
- data/lib/fluent/plugin/node_exporter/cmetrics_dataschema_parser.rb +84 -0
- data/lib/fluent/plugin/node_exporter/collector.rb +41 -0
- data/lib/fluent/plugin/node_exporter/cpu_collector.rb +130 -0
- data/lib/fluent/plugin/node_exporter/cpufreq_collector.rb +97 -0
- data/lib/fluent/plugin/node_exporter/diskstats_collector.rb +280 -0
- data/lib/fluent/plugin/node_exporter/filefd_collector.rb +60 -0
- data/lib/fluent/plugin/node_exporter/loadavg_collector.rb +64 -0
- data/lib/fluent/plugin/node_exporter/meminfo_collector.rb +61 -0
- data/lib/fluent/plugin/node_exporter/netdev_collector.rb +92 -0
- data/lib/fluent/plugin/node_exporter/stat_collector.rb +84 -0
- data/lib/fluent/plugin/node_exporter/time_collector.rb +50 -0
- data/lib/fluent/plugin/node_exporter/uname_collector.rb +64 -0
- data/lib/fluent/plugin/node_exporter/vmstat_collector.rb +56 -0
- data/lib/fluent/plugin/parser_node_exporter_metrics.rb +54 -0
- data/test/fixtures/cpu/with_thermal_throttle/proc/stat +3 -0
- data/test/fixtures/cpu/with_thermal_throttle/sys/devices/system/cpu/cpu0/thermal_throttle/core_throttle_count +1 -0
- data/test/fixtures/cpu/with_thermal_throttle/sys/devices/system/cpu/cpu0/thermal_throttle/package_throttle_count +1 -0
- data/test/fixtures/cpu/with_thermal_throttle/sys/devices/system/cpu/cpu0/topology/core_id +1 -0
- data/test/fixtures/cpu/with_thermal_throttle/sys/devices/system/cpu/cpu0/topology/physical_package_id +1 -0
- data/test/fixtures/cpu/with_thermal_throttle/sys/devices/system/cpu/cpu1/thermal_throttle/core_throttle_count +1 -0
- data/test/fixtures/cpu/with_thermal_throttle/sys/devices/system/cpu/cpu1/thermal_throttle/package_throttle_count +1 -0
- data/test/fixtures/cpu/with_thermal_throttle/sys/devices/system/cpu/cpu1/topology/core_id +1 -0
- data/test/fixtures/cpu/with_thermal_throttle/sys/devices/system/cpu/cpu1/topology/physical_package_id +1 -0
- data/test/fixtures/cpu/without_thermal_throttle/proc/stat +3 -0
- data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq +1 -0
- data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq +1 -0
- data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq +1 -0
- data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq +1 -0
- data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq +1 -0
- data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq +1 -0
- data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_cur_freq +1 -0
- data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_max_freq +1 -0
- data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_min_freq +1 -0
- data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/scaling_cur_freq +1 -0
- data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/scaling_max_freq +1 -0
- data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/scaling_min_freq +1 -0
- data/test/fixtures/cpufreq/without_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq +1 -0
- data/test/fixtures/cpufreq/without_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq +1 -0
- data/test/fixtures/cpufreq/without_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq +1 -0
- data/test/fixtures/cpufreq/without_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq +1 -0
- data/test/fixtures/cpufreq/without_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq +1 -0
- data/test/fixtures/cpufreq/without_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_max_freq +1 -0
- data/test/fixtures/cpufreq/without_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_min_freq +1 -0
- data/test/fixtures/cpufreq/without_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/scaling_cur_freq +1 -0
- data/test/fixtures/cpufreq/without_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/scaling_max_freq +1 -0
- data/test/fixtures/cpufreq/without_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/scaling_min_freq +1 -0
- data/test/helper.rb +24 -0
- data/test/plugin/test_cmetrics_data_schema_parser.rb +83 -0
- data/test/plugin/test_cpu_collector.rb +84 -0
- data/test/plugin/test_cpufreq_collector.rb +75 -0
- data/test/plugin/test_diskstats_collector.rb +200 -0
- data/test/plugin/test_filefd_collector.rb +39 -0
- data/test/plugin/test_in_node_exporter_metrics.rb +583 -0
- data/test/plugin/test_loadavg_collector.rb +41 -0
- data/test/plugin/test_meminfo_collector.rb +47 -0
- data/test/plugin/test_netdev_collector.rb +35 -0
- data/test/plugin/test_stat_collector.rb +37 -0
- data/test/plugin/test_time_collector.rb +15 -0
- data/test/plugin/test_uname_collector.rb +47 -0
- data/test/plugin/test_vmstat_collector.rb +53 -0
- metadata +273 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (C) 2021- Kentaro Hayashi
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
require "cmetrics"
|
|
17
|
+
require "fluent/plugin/input"
|
|
18
|
+
require "fluent/plugin/node_exporter/collector"
|
|
19
|
+
|
|
20
|
+
module Fluent
|
|
21
|
+
module Plugin
|
|
22
|
+
module NodeExporter
|
|
23
|
+
class DiskstatsMetricsCollector < MetricsCollector
|
|
24
|
+
|
|
25
|
+
IGNORED_DEVICES = /^(ram|loop|fd|(h|s|v|xv)d[a-z]|nvme\d+n\d+p)\d+$/
|
|
26
|
+
# https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats
|
|
27
|
+
# major number ... time spent flushing
|
|
28
|
+
DISKSTATS_KNOWN_FIELDS = 20
|
|
29
|
+
# assume sector size = 512
|
|
30
|
+
SECTOR_SIZE = 512
|
|
31
|
+
|
|
32
|
+
METRIC_NAMES = %w(
|
|
33
|
+
reads_completed_total
|
|
34
|
+
reads_merged_total
|
|
35
|
+
read_bytes_total
|
|
36
|
+
read_time_seconds_total
|
|
37
|
+
writes_completed_total
|
|
38
|
+
writes_merged_total
|
|
39
|
+
written_bytes_total
|
|
40
|
+
write_time_seconds_total
|
|
41
|
+
io_now
|
|
42
|
+
io_time_seconds_total
|
|
43
|
+
io_time_weighted_seconds_total
|
|
44
|
+
discards_completed_total
|
|
45
|
+
discards_merged_total
|
|
46
|
+
discarded_sectors_total
|
|
47
|
+
discard_time_seconds_total
|
|
48
|
+
flush_requests_total
|
|
49
|
+
flush_requests_time_seconds_total
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
DISCARD_METRIC_NAMES = %w(
|
|
53
|
+
discards_completed_total
|
|
54
|
+
discards_merged_total
|
|
55
|
+
discarded_sectors_total
|
|
56
|
+
discard_time_seconds_total
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
FLUSH_METRIC_NAMES = %w(
|
|
60
|
+
flush_requests_total
|
|
61
|
+
flush_requests_time_seconds_total
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
def initialize(config={})
|
|
65
|
+
super(config)
|
|
66
|
+
|
|
67
|
+
@reads_completed_total = CMetrics::Counter.new
|
|
68
|
+
@reads_completed_total.create("node", "disk", "reads_completed_total",
|
|
69
|
+
"The total number of reads completed successfully.",
|
|
70
|
+
["device"])
|
|
71
|
+
|
|
72
|
+
@reads_merged_total = CMetrics::Counter.new
|
|
73
|
+
@reads_merged_total.create("node", "disk", "reads_merged_total",
|
|
74
|
+
"The total number of reads merged.",
|
|
75
|
+
["device"])
|
|
76
|
+
|
|
77
|
+
@read_bytes_total = CMetrics::Counter.new
|
|
78
|
+
@read_bytes_total.create("node", "disk", "read_bytes_total",
|
|
79
|
+
"The total number of bytes read successfully.",
|
|
80
|
+
["device"])
|
|
81
|
+
|
|
82
|
+
@read_time_seconds_total = CMetrics::Counter.new
|
|
83
|
+
@read_time_seconds_total.create("node", "disk", "reads_time_seconds_total",
|
|
84
|
+
"The total number of seconds spent by all reads.",
|
|
85
|
+
["device"])
|
|
86
|
+
|
|
87
|
+
@writes_completed_total = CMetrics::Counter.new
|
|
88
|
+
@writes_completed_total.create("node", "disk", "writes_completed_total",
|
|
89
|
+
"The total number of writes completed successfully.",
|
|
90
|
+
["device"])
|
|
91
|
+
|
|
92
|
+
@writes_merged_total = CMetrics::Counter.new
|
|
93
|
+
@writes_merged_total.create("node", "disk", "writes_merged_total",
|
|
94
|
+
"The number of writes merged.",
|
|
95
|
+
["device"])
|
|
96
|
+
|
|
97
|
+
@written_bytes_total = CMetrics::Counter.new
|
|
98
|
+
@written_bytes_total.create("node", "disk", "written_bytes_total",
|
|
99
|
+
"The total number of bytes written successfully.",
|
|
100
|
+
["device"])
|
|
101
|
+
|
|
102
|
+
@write_time_seconds_total = CMetrics::Counter.new
|
|
103
|
+
@write_time_seconds_total.create("node", "disk", "write_time_seconds_total",
|
|
104
|
+
"This is the total number of seconds spent by all writes.",
|
|
105
|
+
["device"])
|
|
106
|
+
|
|
107
|
+
@io_now = CMetrics::Gauge.new
|
|
108
|
+
@io_now.create("node", "disk", "io_now",
|
|
109
|
+
"The number of I/Os currently in progress.",
|
|
110
|
+
["device"])
|
|
111
|
+
|
|
112
|
+
@io_time_seconds_total = CMetrics::Counter.new
|
|
113
|
+
@io_time_seconds_total.create("node", "disk", "io_time_seconds_total",
|
|
114
|
+
"Total seconds spent doing I/Os.",
|
|
115
|
+
["device"])
|
|
116
|
+
|
|
117
|
+
@io_time_weighted_seconds_total = CMetrics::Counter.new
|
|
118
|
+
@io_time_weighted_seconds_total.create("node", "disk", "io_time_weighted_seconds_total",
|
|
119
|
+
"The number of I/Os currently in progress.",
|
|
120
|
+
["device"])
|
|
121
|
+
|
|
122
|
+
if kernel_version_over4_18?
|
|
123
|
+
# Kernel >= 4.18
|
|
124
|
+
@discards_completed_total = CMetrics::Counter.new
|
|
125
|
+
@discards_completed_total.create("node", "disk", "discards_completed_total",
|
|
126
|
+
"The total number of discards completed successfully.",
|
|
127
|
+
["device"])
|
|
128
|
+
|
|
129
|
+
@discards_merged_total = CMetrics::Counter.new
|
|
130
|
+
@discards_merged_total.create("node", "disk", "discards_merged_total",
|
|
131
|
+
"The total number of discards merged.", ["device"])
|
|
132
|
+
|
|
133
|
+
@discarded_sectors_total = CMetrics::Counter.new
|
|
134
|
+
@discarded_sectors_total.create("node", "disk", "discards_sectors_total",
|
|
135
|
+
"The total number of sectors discarded successfully.",
|
|
136
|
+
["device"])
|
|
137
|
+
|
|
138
|
+
@discard_time_seconds_total = CMetrics::Counter.new
|
|
139
|
+
@discard_time_seconds_total.create("node", "disk", "discard_time_seconds_total",
|
|
140
|
+
"The total number of seconds spent by all discards.",
|
|
141
|
+
["device"])
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
if kernel_version_over5_5?
|
|
145
|
+
@flush_requests_total = CMetrics::Counter.new
|
|
146
|
+
@flush_requests_total.create("node", "disk", "flush_requests_total",
|
|
147
|
+
"The total number of flush requests completed successfully",
|
|
148
|
+
["device"])
|
|
149
|
+
|
|
150
|
+
@flush_requests_time_seconds_total = CMetrics::Counter.new
|
|
151
|
+
@flush_requests_time_seconds_total.create("node", "disk", "flush_requests_time_seconds_total",
|
|
152
|
+
"This is the total number of seconds spent by all flush requests.",
|
|
153
|
+
["device"])
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
@metrics = {}
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def kernel_version_over4_18?
|
|
160
|
+
Gem::Version.new(Etc.uname[:release].split('-', 2).first) >= Gem::Version.new("4.18")
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def kernel_version_over5_5?
|
|
164
|
+
Gem::Version.new(Etc.uname[:release].split('-', 2).first) >= Gem::Version.new("5.5.0")
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def target_devices
|
|
168
|
+
devices = []
|
|
169
|
+
diskstats_path = File.join(@procfs_path, "diskstats")
|
|
170
|
+
File.readlines(diskstats_path).each do |line|
|
|
171
|
+
_, _, device, _ = line.split(' ', DISKSTATS_KNOWN_FIELDS)
|
|
172
|
+
unless IGNORED_DEVICES.match?(device)
|
|
173
|
+
devices << device
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
devices
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def run
|
|
180
|
+
diskstats_update
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def diskstats_update
|
|
184
|
+
diskstats_path = File.join(@procfs_path, "diskstats")
|
|
185
|
+
File.readlines(diskstats_path).each do |line|
|
|
186
|
+
_, _, device,
|
|
187
|
+
reads_completed_value, reads_merged_value, read_bytes_value, read_time_seconds_value,
|
|
188
|
+
writes_completed_value, writes_merged_value, written_bytes_value, write_time_seconds_value,
|
|
189
|
+
io_now_value, io_time_seconds_value, io_time_weighted_seconds_value,
|
|
190
|
+
discards_completed_value, discards_merged_value, discarded_sectors_value, discard_time_seconds_value,
|
|
191
|
+
flush_requests_value, flush_requests_time_seconds_value = line.split(' ', DISKSTATS_KNOWN_FIELDS)
|
|
192
|
+
unless IGNORED_DEVICES.match?(device)
|
|
193
|
+
METRIC_NAMES.each do |field|
|
|
194
|
+
case field
|
|
195
|
+
when "reads_completed_total"
|
|
196
|
+
@reads_completed_total.set(reads_completed_value.to_f, [device])
|
|
197
|
+
when "reads_merged_total"
|
|
198
|
+
@reads_merged_total.set(reads_merged_value.to_f, [device])
|
|
199
|
+
when "read_bytes_total"
|
|
200
|
+
@read_bytes_total.set(read_bytes_value.to_f * SECTOR_SIZE, [device])
|
|
201
|
+
when "read_time_seconds_total"
|
|
202
|
+
@read_time_seconds_total.set(read_time_seconds_value.to_f * 0.001, [device])
|
|
203
|
+
when "writes_completed_total"
|
|
204
|
+
@writes_completed_total.set(writes_completed_value.to_f, [device])
|
|
205
|
+
when "writes_merged_total"
|
|
206
|
+
@writes_merged_total.set(writes_merged_value.to_f, [device])
|
|
207
|
+
when "written_bytes_total"
|
|
208
|
+
@written_bytes_total.set(written_bytes_value.to_f * SECTOR_SIZE, [device])
|
|
209
|
+
when "write_time_seconds_total"
|
|
210
|
+
@write_time_seconds_total.set(write_time_seconds_value.to_f * 0.001, [device])
|
|
211
|
+
when "io_now"
|
|
212
|
+
@io_now.set(io_now_value.to_f, [device])
|
|
213
|
+
when "io_time_seconds_total"
|
|
214
|
+
@io_time_seconds_total.set(io_time_seconds_value.to_f * 0.001, [device])
|
|
215
|
+
when "io_time_weighted_seconds_total"
|
|
216
|
+
@io_time_weighted_seconds_total.set(io_time_weighted_seconds_value.to_f * 0.001, [device])
|
|
217
|
+
when "discards_completed_total"
|
|
218
|
+
if kernel_version_over4_18?
|
|
219
|
+
@discards_completed_total.set(discards_completed_value.to_f, [device])
|
|
220
|
+
end
|
|
221
|
+
when "discards_merged_total"
|
|
222
|
+
if kernel_version_over4_18?
|
|
223
|
+
@discards_merged_total.set(discards_merged_value.to_f, [device])
|
|
224
|
+
end
|
|
225
|
+
when "discarded_sectors_total"
|
|
226
|
+
if kernel_version_over4_18?
|
|
227
|
+
@discarded_sectors_total.set(discarded_sectors_value.to_f, [device])
|
|
228
|
+
end
|
|
229
|
+
when "discard_time_seconds_total"
|
|
230
|
+
if kernel_version_over4_18?
|
|
231
|
+
@discard_time_seconds_total.set(discard_time_seconds_value.to_f * 0.001, [device])
|
|
232
|
+
end
|
|
233
|
+
when "flush_requests_total"
|
|
234
|
+
if kernel_version_over5_5?
|
|
235
|
+
@flush_requests_total.set(flush_requests_value.to_f, [device])
|
|
236
|
+
end
|
|
237
|
+
when "flush_requests_time_seconds_total"
|
|
238
|
+
if kernel_version_over5_5?
|
|
239
|
+
@flush_requests_time_seconds_total.set(flush_requests_time_seconds_value.to_f * 0.001, [device])
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
@metrics = {
|
|
244
|
+
reads_completed_total: @reads_completed_total,
|
|
245
|
+
reads_merged_total: @reads_merged_total,
|
|
246
|
+
read_bytes_total: @read_bytes_total,
|
|
247
|
+
read_time_seconds_total: @read_time_seconds_total,
|
|
248
|
+
writes_completed_total: @writes_completed_total,
|
|
249
|
+
writes_merged_total: @writes_merged_total,
|
|
250
|
+
written_bytes_total: @written_bytes_total,
|
|
251
|
+
write_time_seconds_total: @write_time_seconds_total,
|
|
252
|
+
io_now: @io_now,
|
|
253
|
+
io_time_seconds_total: @io_time_seconds_total,
|
|
254
|
+
io_time_weighted_seconds_total: @io_time_weighted_seconds_total
|
|
255
|
+
}
|
|
256
|
+
if kernel_version_over4_18?
|
|
257
|
+
@metrics.merge!({
|
|
258
|
+
discards_completed_total: @discards_completed_total,
|
|
259
|
+
discards_merged_total: @discards_merged_total,
|
|
260
|
+
discarded_sectors_total: @discarded_sectors_total,
|
|
261
|
+
discard_time_seconds_total: @discard_time_seconds_total
|
|
262
|
+
})
|
|
263
|
+
end
|
|
264
|
+
if kernel_version_over5_5?
|
|
265
|
+
@metrics.merge!({
|
|
266
|
+
flush_requests_total: @flush_requests_total,
|
|
267
|
+
flush_requests_time_seconds_total: @flush_requests_time_seconds_total
|
|
268
|
+
})
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def cmetrics
|
|
275
|
+
@metrics
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2021- Kentaro Hayashi
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
require "cmetrics"
|
|
17
|
+
require "fluent/plugin/input"
|
|
18
|
+
require "fluent/plugin/node_exporter/collector"
|
|
19
|
+
|
|
20
|
+
module Fluent
|
|
21
|
+
module Plugin
|
|
22
|
+
module NodeExporter
|
|
23
|
+
class FilefdMetricsCollector < MetricsCollector
|
|
24
|
+
def initialize(config={})
|
|
25
|
+
super(config)
|
|
26
|
+
|
|
27
|
+
@allocated = CMetrics::Gauge.new
|
|
28
|
+
@allocated.create("node", "filefd", "allocated", "File descriptor statistics: allocated.")
|
|
29
|
+
|
|
30
|
+
@maximum = CMetrics::Gauge.new
|
|
31
|
+
@maximum.create("node", "filefd", "maximum", "File descriptor statistics: maximum.")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def run
|
|
35
|
+
filefd_update
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def filefd_update
|
|
39
|
+
# Etc.uname returns at least sysname,release,version,machine,nodename
|
|
40
|
+
# but it is not guaranteed to return domainname.
|
|
41
|
+
file_nr_path = File.join(@procfs_path, "/sys/fs/file-nr")
|
|
42
|
+
entry = File.read(file_nr_path).split
|
|
43
|
+
unless entry.size == 3
|
|
44
|
+
$log.warn("invalid number of field <#{file_nr_path}>: #{entry.size}")
|
|
45
|
+
return
|
|
46
|
+
end
|
|
47
|
+
@allocated.set(entry.first.to_f)
|
|
48
|
+
@maximum.set(entry.last.to_f)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def cmetrics
|
|
52
|
+
{
|
|
53
|
+
filefd_allocated: @allocated,
|
|
54
|
+
filefd_maximum: @maximum
|
|
55
|
+
}
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2021- Kentaro Hayashi
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
require "cmetrics"
|
|
17
|
+
require "fluent/plugin/input"
|
|
18
|
+
require "fluent/plugin/node_exporter/collector"
|
|
19
|
+
|
|
20
|
+
module Fluent
|
|
21
|
+
module Plugin
|
|
22
|
+
module NodeExporter
|
|
23
|
+
class LoadavgMetricsCollector < MetricsCollector
|
|
24
|
+
def initialize(config={})
|
|
25
|
+
super(config)
|
|
26
|
+
|
|
27
|
+
@load1 = CMetrics::Gauge.new
|
|
28
|
+
@load1.create("node", "", "load1", "1m load average.")
|
|
29
|
+
|
|
30
|
+
@load5 = CMetrics::Gauge.new
|
|
31
|
+
@load5.create("node", "", "load5", "5m load average.")
|
|
32
|
+
|
|
33
|
+
@load15 = CMetrics::Gauge.new
|
|
34
|
+
@load15.create("node", "", "load15", "15m load average.")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def run
|
|
38
|
+
loadavg_update
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def loadavg_update
|
|
42
|
+
loadavg_path = File.join(@procfs_path, "/loadavg")
|
|
43
|
+
# Use 1 explicitly for default gauge value
|
|
44
|
+
fields = File.read(loadavg_path).split
|
|
45
|
+
unless fields.size == 5
|
|
46
|
+
$log.warn("invalid number of fields <#{loadavg_path}>: <#{fields.size}>")
|
|
47
|
+
return
|
|
48
|
+
end
|
|
49
|
+
@load1.set(fields[0].to_f)
|
|
50
|
+
@load5.set(fields[1].to_f)
|
|
51
|
+
@load15.set(fields[2].to_f)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def cmetrics
|
|
55
|
+
{
|
|
56
|
+
loadavg1: @load1,
|
|
57
|
+
loadavg5: @load5,
|
|
58
|
+
loadavg15: @load15
|
|
59
|
+
}
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2021- Kentaro Hayashi
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
require "cmetrics"
|
|
17
|
+
require "fluent/plugin/input"
|
|
18
|
+
require "fluent/plugin/node_exporter/collector"
|
|
19
|
+
|
|
20
|
+
module Fluent
|
|
21
|
+
module Plugin
|
|
22
|
+
module NodeExporter
|
|
23
|
+
class MeminfoMetricsCollector < MetricsCollector
|
|
24
|
+
|
|
25
|
+
def initialize(config={})
|
|
26
|
+
super(config)
|
|
27
|
+
|
|
28
|
+
@metrics = {}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def run
|
|
32
|
+
meminfo_update
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def meminfo_update
|
|
36
|
+
meminfo_path = File.join(@procfs_path, "meminfo")
|
|
37
|
+
File.readlines(meminfo_path).each do |line|
|
|
38
|
+
name, value, unit = line.split
|
|
39
|
+
name.delete!(":")
|
|
40
|
+
if name.end_with?("(anon)") or name.end_with?("(file)")
|
|
41
|
+
name.sub!(/\((anon)\)|\((file)\)/, "_\\1\\2")
|
|
42
|
+
end
|
|
43
|
+
if unit
|
|
44
|
+
name << "_bytes"
|
|
45
|
+
value = value.to_f * 1024
|
|
46
|
+
end
|
|
47
|
+
metric_name = "node_memory_#{name}"
|
|
48
|
+
@gauge = CMetrics::Gauge.new
|
|
49
|
+
@gauge.create("node", "memory", name, "#{name}.")
|
|
50
|
+
@gauge.set(value.to_f)
|
|
51
|
+
@metrics[metric_name.intern] = @gauge
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def cmetrics
|
|
56
|
+
@metrics
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2021- Kentaro Hayashi
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
require "cmetrics"
|
|
17
|
+
require "fluent/plugin/input"
|
|
18
|
+
require "fluent/plugin/node_exporter/collector"
|
|
19
|
+
|
|
20
|
+
module Fluent
|
|
21
|
+
module Plugin
|
|
22
|
+
module NodeExporter
|
|
23
|
+
class NetdevMetricsCollector < MetricsCollector
|
|
24
|
+
|
|
25
|
+
def initialize(config={})
|
|
26
|
+
super(config)
|
|
27
|
+
|
|
28
|
+
@metrics = {}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def run
|
|
32
|
+
netdev_update
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
RECEIVE_FIELDS = %w(bytes packets errs drop fifo frame compressed multicast)
|
|
36
|
+
TRANSMIT_FIELDS = %w(bytes packets errs drop fifo colls carrier compressed)
|
|
37
|
+
|
|
38
|
+
def target_devices
|
|
39
|
+
devices = []
|
|
40
|
+
netdev_path = File.join(@procfs_path, "net/dev")
|
|
41
|
+
File.readlines(netdev_path).each_with_index do |line, index|
|
|
42
|
+
next if index < 2
|
|
43
|
+
interface, _ = line.split
|
|
44
|
+
interface.delete!(":")
|
|
45
|
+
devices << interface
|
|
46
|
+
end
|
|
47
|
+
devices
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def netdev_update
|
|
51
|
+
netdev_path = File.join(@procfs_path, "net/dev")
|
|
52
|
+
RECEIVE_FIELDS.each_with_index do |field, index|
|
|
53
|
+
metric_name = "receive_#{field}_total"
|
|
54
|
+
@counter = CMetrics::Counter.new
|
|
55
|
+
@counter.create("node", "network", metric_name, "Network device statistic #{metric_name}.", ["device"])
|
|
56
|
+
@metrics[metric_name.intern] = @counter
|
|
57
|
+
end
|
|
58
|
+
TRANSMIT_FIELDS.each_with_index do |field, index|
|
|
59
|
+
metric_name = "transmit_#{field}_total"
|
|
60
|
+
@counter = CMetrics::Counter.new
|
|
61
|
+
@counter.create("node", "network", metric_name, "Network device statistic #{metric_name}.", ["device"])
|
|
62
|
+
@metrics[metric_name.intern] = @counter
|
|
63
|
+
end
|
|
64
|
+
File.readlines(netdev_path).each_with_index do |line, index|
|
|
65
|
+
# net/dev must be 3 columns
|
|
66
|
+
if index == 0 and line.split("|").size != 3
|
|
67
|
+
break
|
|
68
|
+
end
|
|
69
|
+
# first 2 line are header (Inter-face/Receive/Transmit)
|
|
70
|
+
next if index < 2
|
|
71
|
+
|
|
72
|
+
interface, *values = line.split
|
|
73
|
+
interface.delete!(":")
|
|
74
|
+
|
|
75
|
+
RECEIVE_FIELDS.each_with_index do |field, index|
|
|
76
|
+
metric_name = "receive_#{field}_total"
|
|
77
|
+
@metrics[metric_name.intern].set(values[index].to_f, [interface])
|
|
78
|
+
end
|
|
79
|
+
TRANSMIT_FIELDS.each_with_index do |field, index|
|
|
80
|
+
metric_name = "transmit_#{field}_total"
|
|
81
|
+
@metrics[metric_name.intern].set(values[index + RECEIVE_FIELDS.size].to_f, [interface])
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def cmetrics
|
|
87
|
+
@metrics
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2021- Kentaro Hayashi
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
require "cmetrics"
|
|
17
|
+
require "fluent/plugin/input"
|
|
18
|
+
require "fluent/plugin/node_exporter/collector"
|
|
19
|
+
|
|
20
|
+
module Fluent
|
|
21
|
+
module Plugin
|
|
22
|
+
module NodeExporter
|
|
23
|
+
class StatMetricsCollector < MetricsCollector
|
|
24
|
+
def initialize(config={})
|
|
25
|
+
super(config)
|
|
26
|
+
|
|
27
|
+
@intr_total = CMetrics::Counter.new
|
|
28
|
+
@intr_total.create("node", "", "intr_total", "Total number of interrupts serviced.")
|
|
29
|
+
|
|
30
|
+
@context_switches_total = CMetrics::Counter.new
|
|
31
|
+
@context_switches_total.create("node", "", "context_switches_total", "Total number of context switches.")
|
|
32
|
+
|
|
33
|
+
@forks_total = CMetrics::Counter.new
|
|
34
|
+
@forks_total.create("node", "", "forks_total", "Total number of forks.")
|
|
35
|
+
|
|
36
|
+
@boot_time_seconds = CMetrics::Gauge.new
|
|
37
|
+
@boot_time_seconds.create("node", "", "boot_time_seconds", "Node boot time, in unixtime.")
|
|
38
|
+
|
|
39
|
+
@procs_running = CMetrics::Gauge.new
|
|
40
|
+
@procs_running.create("node", "", "procs_running", "Number of processes in runnable state.")
|
|
41
|
+
|
|
42
|
+
@procs_blocked = CMetrics::Gauge.new
|
|
43
|
+
@procs_blocked.create("node", "", "procs_blocked", "Number of processes blocked waiting for I/O to complete.")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def run
|
|
47
|
+
stat_update
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def stat_update
|
|
51
|
+
stat_path = File.join(@procfs_path, "stat")
|
|
52
|
+
File.readlines(stat_path).each do |line|
|
|
53
|
+
entry, value, _ = line.split
|
|
54
|
+
case entry
|
|
55
|
+
when "intr"
|
|
56
|
+
@intr_total.set(value.to_f)
|
|
57
|
+
when "ctxt"
|
|
58
|
+
@context_switches_total.set(value.to_f)
|
|
59
|
+
when "btime"
|
|
60
|
+
@boot_time_seconds.set(value.to_f)
|
|
61
|
+
when "processes"
|
|
62
|
+
@forks_total.set(value.to_f)
|
|
63
|
+
when "procs_running"
|
|
64
|
+
@procs_running.set(value.to_f)
|
|
65
|
+
when "procs_blocked"
|
|
66
|
+
@procs_blocked.set(value.to_f)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def cmetrics
|
|
72
|
+
{
|
|
73
|
+
intr_total: @intr_total,
|
|
74
|
+
context_switches_total: @context_switches_total,
|
|
75
|
+
forks_total: @forks_total,
|
|
76
|
+
boot_time_seconds: @boot_time_seconds,
|
|
77
|
+
procs_running: @procs_running,
|
|
78
|
+
procs_blocked: @procs_blocked
|
|
79
|
+
}
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|