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.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/linux-test.yaml +42 -0
  3. data/.gitignore +2 -0
  4. data/CHANGELOG.md +6 -0
  5. data/Gemfile +3 -0
  6. data/LICENSE +202 -0
  7. data/README.md +167 -0
  8. data/Rakefile +13 -0
  9. data/docs/cpu.md +26 -0
  10. data/docs/cpufreq.md +43 -0
  11. data/docs/diskstats.md +27 -0
  12. data/docs/filefd.md +12 -0
  13. data/docs/loadavg.md +13 -0
  14. data/docs/meminfo.md +61 -0
  15. data/docs/netdev.md +26 -0
  16. data/docs/stat.md +17 -0
  17. data/docs/time.md +9 -0
  18. data/docs/uname.md +15 -0
  19. data/docs/vmstat.md +17 -0
  20. data/fluent-plugin-node-exporter-metrics.gemspec +31 -0
  21. data/lib/fluent/plugin/in_node_exporter_metrics.rb +138 -0
  22. data/lib/fluent/plugin/node_exporter/cmetrics_dataschema_parser.rb +84 -0
  23. data/lib/fluent/plugin/node_exporter/collector.rb +41 -0
  24. data/lib/fluent/plugin/node_exporter/cpu_collector.rb +130 -0
  25. data/lib/fluent/plugin/node_exporter/cpufreq_collector.rb +97 -0
  26. data/lib/fluent/plugin/node_exporter/diskstats_collector.rb +280 -0
  27. data/lib/fluent/plugin/node_exporter/filefd_collector.rb +60 -0
  28. data/lib/fluent/plugin/node_exporter/loadavg_collector.rb +64 -0
  29. data/lib/fluent/plugin/node_exporter/meminfo_collector.rb +61 -0
  30. data/lib/fluent/plugin/node_exporter/netdev_collector.rb +92 -0
  31. data/lib/fluent/plugin/node_exporter/stat_collector.rb +84 -0
  32. data/lib/fluent/plugin/node_exporter/time_collector.rb +50 -0
  33. data/lib/fluent/plugin/node_exporter/uname_collector.rb +64 -0
  34. data/lib/fluent/plugin/node_exporter/vmstat_collector.rb +56 -0
  35. data/lib/fluent/plugin/parser_node_exporter_metrics.rb +54 -0
  36. data/test/fixtures/cpu/with_thermal_throttle/proc/stat +3 -0
  37. data/test/fixtures/cpu/with_thermal_throttle/sys/devices/system/cpu/cpu0/thermal_throttle/core_throttle_count +1 -0
  38. data/test/fixtures/cpu/with_thermal_throttle/sys/devices/system/cpu/cpu0/thermal_throttle/package_throttle_count +1 -0
  39. data/test/fixtures/cpu/with_thermal_throttle/sys/devices/system/cpu/cpu0/topology/core_id +1 -0
  40. data/test/fixtures/cpu/with_thermal_throttle/sys/devices/system/cpu/cpu0/topology/physical_package_id +1 -0
  41. data/test/fixtures/cpu/with_thermal_throttle/sys/devices/system/cpu/cpu1/thermal_throttle/core_throttle_count +1 -0
  42. data/test/fixtures/cpu/with_thermal_throttle/sys/devices/system/cpu/cpu1/thermal_throttle/package_throttle_count +1 -0
  43. data/test/fixtures/cpu/with_thermal_throttle/sys/devices/system/cpu/cpu1/topology/core_id +1 -0
  44. data/test/fixtures/cpu/with_thermal_throttle/sys/devices/system/cpu/cpu1/topology/physical_package_id +1 -0
  45. data/test/fixtures/cpu/without_thermal_throttle/proc/stat +3 -0
  46. data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq +1 -0
  47. data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq +1 -0
  48. data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq +1 -0
  49. data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq +1 -0
  50. data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq +1 -0
  51. data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq +1 -0
  52. data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_cur_freq +1 -0
  53. data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_max_freq +1 -0
  54. data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_min_freq +1 -0
  55. data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/scaling_cur_freq +1 -0
  56. data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/scaling_max_freq +1 -0
  57. data/test/fixtures/cpufreq/with_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/scaling_min_freq +1 -0
  58. data/test/fixtures/cpufreq/without_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq +1 -0
  59. data/test/fixtures/cpufreq/without_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq +1 -0
  60. data/test/fixtures/cpufreq/without_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq +1 -0
  61. data/test/fixtures/cpufreq/without_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq +1 -0
  62. data/test/fixtures/cpufreq/without_cur_freq/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq +1 -0
  63. data/test/fixtures/cpufreq/without_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_max_freq +1 -0
  64. data/test/fixtures/cpufreq/without_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_min_freq +1 -0
  65. data/test/fixtures/cpufreq/without_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/scaling_cur_freq +1 -0
  66. data/test/fixtures/cpufreq/without_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/scaling_max_freq +1 -0
  67. data/test/fixtures/cpufreq/without_cur_freq/sys/devices/system/cpu/cpu1/cpufreq/scaling_min_freq +1 -0
  68. data/test/helper.rb +24 -0
  69. data/test/plugin/test_cmetrics_data_schema_parser.rb +83 -0
  70. data/test/plugin/test_cpu_collector.rb +84 -0
  71. data/test/plugin/test_cpufreq_collector.rb +75 -0
  72. data/test/plugin/test_diskstats_collector.rb +200 -0
  73. data/test/plugin/test_filefd_collector.rb +39 -0
  74. data/test/plugin/test_in_node_exporter_metrics.rb +583 -0
  75. data/test/plugin/test_loadavg_collector.rb +41 -0
  76. data/test/plugin/test_meminfo_collector.rb +47 -0
  77. data/test/plugin/test_netdev_collector.rb +35 -0
  78. data/test/plugin/test_stat_collector.rb +37 -0
  79. data/test/plugin/test_time_collector.rb +15 -0
  80. data/test/plugin/test_uname_collector.rb +47 -0
  81. data/test/plugin/test_vmstat_collector.rb +53 -0
  82. metadata +273 -0
@@ -0,0 +1,50 @@
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 TimeMetricsCollector < MetricsCollector
24
+ def initialize(config={})
25
+ super(config)
26
+
27
+ @gauge = CMetrics::Gauge.new
28
+ @gauge.create("node", "", "time_seconds",
29
+ "System time in seconds since epoch (1970).")
30
+ end
31
+
32
+ def run
33
+ time_update
34
+ end
35
+
36
+ def time_update
37
+ current_time = Fluent::EventTime.now
38
+ value = current_time.to_i / 1e9
39
+ @gauge.set(value)
40
+ end
41
+
42
+ def cmetrics
43
+ {
44
+ time_seconds: @gauge
45
+ }
46
+ end
47
+ end
48
+ end
49
+ end
50
+ 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 "etc"
18
+ require "fluent/plugin/input"
19
+ require "fluent/plugin/node_exporter/collector"
20
+
21
+ module Fluent
22
+ module Plugin
23
+ module NodeExporter
24
+ class UnameMetricsCollector < MetricsCollector
25
+ def initialize(config={})
26
+ super(config)
27
+
28
+ @gauge = CMetrics::Gauge.new
29
+ @gauge.create("node", "uname", "info",
30
+ "Labeled system information as provided by the uname system call.",
31
+ ["sysname", "release", "version", "machine", "nodename", "domainname"])
32
+ end
33
+
34
+ def run
35
+ uname_update
36
+ end
37
+
38
+ def uname_update
39
+ # Etc.uname returns at least sysname,release,version,machine,nodename
40
+ # but it is not guaranteed to return domainname.
41
+ domainname = if Etc.uname.has_key?(:domainname)
42
+ Etc.uname[:domainname]
43
+ else
44
+ "(none)"
45
+ end
46
+ # Use 1 explicitly for default gauge value
47
+ @gauge.set(1, [
48
+ Etc.uname[:sysname],
49
+ Etc.uname[:release],
50
+ Etc.uname[:version],
51
+ Etc.uname[:machine],
52
+ Etc.uname[:nodename],
53
+ domainname])
54
+ end
55
+
56
+ def cmetrics
57
+ {
58
+ info: @gauge
59
+ }
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,56 @@
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 VmstatMetricsCollector < MetricsCollector
24
+
25
+ VMSTAT_ENTRIES_REGEX = /^(oom_kill|pgpg|pswp|pg.*fault).*/
26
+
27
+ def initialize(config={})
28
+ super(config)
29
+
30
+ @metrics = {}
31
+ end
32
+
33
+ def run
34
+ vmstat_update
35
+ end
36
+
37
+ def vmstat_update
38
+ vmstat_path = File.join(@procfs_path, "vmstat")
39
+ File.readlines(vmstat_path).each do |line|
40
+ if VMSTAT_ENTRIES_REGEX.match?(line)
41
+ key, value = line.split(' ', 2)
42
+ @untyped = CMetrics::Untyped.new
43
+ @untyped.create("node", "vmstat", key, "#{vmstat_path} information field #{key}.")
44
+ @untyped.set(value.to_f)
45
+ @metrics[key.intern] = @untyped
46
+ end
47
+ end
48
+ end
49
+
50
+ def cmetrics
51
+ @metrics
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,54 @@
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 "fluent/plugin/parser"
17
+ require "fluent/msgpack_factory"
18
+
19
+ require "fluent/plugin/node_exporter/cmetrics_dataschema_parser"
20
+
21
+ module Fluent
22
+ module Plugin
23
+ class NodeExporterMetricsParser < Parser
24
+ Plugin.register_parser('node_exporter_metrics', self)
25
+
26
+ def configure(conf)
27
+ super
28
+ @unpacker = Fluent::MessagePackFactory.engine_factory.unpacker
29
+ @parser = Fluent::Plugin::NodeExporter::CMetricsDataSchemaParser.new
30
+ end
31
+
32
+ def parser_type
33
+ :binary
34
+ end
35
+
36
+ def parse(data)
37
+ @unpacker.feed_each(data) do |obj|
38
+ metrics = @parser.parse(obj)
39
+ yield Fluent::EventTime.now, metrics
40
+ end
41
+ end
42
+
43
+ alias parse_partial_data parse
44
+
45
+ def parse_io(io, &block)
46
+ u = Fluent::MessagePackFactory.engine_factory.unpacker(io)
47
+ u.each do |obj|
48
+ metrics = @parser.parse(obj)
49
+ yield Fluent::EventTime.now, metrics
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,3 @@
1
+ cpu 464630 486 142953 41892706 67964 0 33936 0 0 0
2
+ cpu0 1000 2000 3000 4000 5000 6000 7000 8000 9000 10000
3
+ cpu1 30454 2400 7030 2620182 3768 0 5700 0 0 0
@@ -0,0 +1,3 @@
1
+ cpu 464630 486 142953 41892706 67964 0 33936 0 0 0
2
+ cpu0 1000 2000 3000 4000 5000 6000 7000 8000 9000 10000
3
+ cpu1 30454 2400 7030 2620182 3768 0 5700 0 0 0
data/test/helper.rb ADDED
@@ -0,0 +1,24 @@
1
+ $LOAD_PATH.unshift(File.expand_path("../../", __FILE__))
2
+ require "test-unit"
3
+ require "test/unit/rr"
4
+ require "fluent/test"
5
+ require "fluent/test/driver/input"
6
+ require "fluent/test/helpers"
7
+ require "fluent/plugin/in_node_exporter_metrics"
8
+
9
+ Test::Unit::TestCase.include(Fluent::Test::Helpers)
10
+ Test::Unit::TestCase.extend(Fluent::Test::Helpers)
11
+
12
+ def fixture_filesystem_root(collector, test_case, filesystem)
13
+ File.expand_path(File.join(File.dirname(__FILE__), "fixtures",
14
+ collector, test_case, filesystem))
15
+ end
16
+
17
+ def fixture_sysfs_root(collector, test_case="")
18
+ fixture_filesystem_root(collector, test_case, "sys")
19
+ end
20
+
21
+ def fixture_procfs_root(collector, test_case="")
22
+ fixture_filesystem_root(collector, test_case, "proc")
23
+ end
24
+
@@ -0,0 +1,83 @@
1
+ require "helper"
2
+ require "fluent/plugin/node_exporter/cmetrics_dataschema_parser"
3
+
4
+ class CMetricsDataSchemaParserTest < Test::Unit::TestCase
5
+
6
+ NSEC_IN_SECONDS = 1000 * 1000 * 1000
7
+
8
+ setup do
9
+ @parser = Fluent::Plugin::NodeExporter::CMetricsDataSchemaParser.new
10
+ @nsecs = Time.parse("2021/09/01").to_i * NSEC_IN_SECONDS
11
+ end
12
+
13
+ sub_test_case "parser" do
14
+ def test_without_labels
15
+ objs = [{"meta"=>
16
+ {"ver"=>2,
17
+ "type"=>1,
18
+ "opts"=>
19
+ {"ns"=>"node",
20
+ "ss"=>"",
21
+ "name"=>"time_seconds",
22
+ "desc"=>"System time in seconds since epoch (1970)."},
23
+ "label_dictionary"=>[],
24
+ "static_labels"=>[],
25
+ "labels"=>[]},
26
+ "values"=>[{"ts"=>@nsecs, "value"=>1.632131027}]}]
27
+ assert_equal([
28
+ {
29
+ "desc"=>"System time in seconds since epoch (1970).",
30
+ "name"=>"node_time_seconds",
31
+ "value"=>1.632131027,
32
+ "ts"=>@nsecs
33
+ }
34
+ ],
35
+ @parser.parse(objs))
36
+ end
37
+
38
+ def test_with_labels
39
+ objs = [{"meta"=>
40
+ {"ver"=>2,
41
+ "type"=>1,
42
+ "opts"=>
43
+ {"ns"=>"node",
44
+ "ss"=>"uname",
45
+ "name"=>"info",
46
+ "desc"=>
47
+ "Labeled system information as provided by the uname system call."},
48
+ "label_dictionary"=>
49
+ ["sysname",
50
+ "release",
51
+ "version",
52
+ "machine",
53
+ "nodename",
54
+ "domainname",
55
+ "Linux",
56
+ "5.10.0-8-amd64",
57
+ "#1 SMP Debian",
58
+ "x86_64",
59
+ "jet",
60
+ "(none)"],
61
+ "static_labels"=>[],
62
+ "labels"=>[0, 1, 2, 3, 4, 5]},
63
+ "values"=>
64
+ [{"ts"=>@nsecs,
65
+ "value"=>1.0,
66
+ "labels"=>[6, 7, 8, 9, 10, 11]}]}]
67
+ assert_equal([
68
+ {"desc"=>"Labeled system information as provided by the uname system call.",
69
+ "labels"=>
70
+ {"domainname"=>"(none)",
71
+ "machine"=>"x86_64",
72
+ "nodename"=>"jet",
73
+ "release"=>"5.10.0-8-amd64",
74
+ "sysname"=>"Linux",
75
+ "version"=>"#1 SMP Debian"},
76
+ "name"=>"node_uname_info",
77
+ "ts"=>@nsecs,
78
+ "value"=>1.0}
79
+ ],
80
+ @parser.parse(objs))
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,84 @@
1
+ require "helper"
2
+ require "fluent/plugin/in_node_exporter_metrics"
3
+ require "fluent/plugin/node_exporter/cpu_collector"
4
+
5
+ class CpuColectorTest < Test::Unit::TestCase
6
+ setup do
7
+ Fluent::Test.setup
8
+ end
9
+
10
+ teardown do
11
+ Fluent::Engine.stop
12
+ end
13
+
14
+ CONFIG = config_element("ROOT", "", {
15
+ "scrape_interval" => 5,
16
+ "procfs_path" => "/proc",
17
+ "sysfs_path" => "/sys"
18
+ })
19
+
20
+ DEFAULT_COLLECTORS = CONFIG + config_element("", "", {
21
+ })
22
+
23
+ def create_driver(conf = CONFIG)
24
+ Fluent::Test::Driver::Input.new(Fluent::Plugin::NodeExporterMetricsInput).configure(conf)
25
+ end
26
+
27
+ sub_test_case "cpu_thermal_throttle" do
28
+ def test_cpu_thermal_throttle
29
+ config = {
30
+ scpape_interval: 1,
31
+ procfs_path: fixture_procfs_root("cpu", "with_thermal_throttle"),
32
+ sysfs_path: fixture_sysfs_root("cpu", "with_thermal_throttle")
33
+ }
34
+ collector = Fluent::Plugin::NodeExporter::CpuMetricsCollector.new(config)
35
+ collector.run
36
+ # CPU0/1 thermal throttle
37
+ core_throttles_total = collector.cmetrics[:core_throttles_total]
38
+ package_throttles_total = collector.cmetrics[:package_throttles_total]
39
+ assert_equal([1.0, 2.0, 10.0],
40
+ [core_throttles_total.val(["0", "0"]),
41
+ core_throttles_total.val(["1", "0"]),
42
+ package_throttles_total.val(["0"])
43
+ ])
44
+ end
45
+
46
+ def test_without_cpu_thermal_throttle
47
+ config = {
48
+ scpape_interval: 1,
49
+ procfs_path: fixture_procfs_root("cpu", "without_thermal_throttle"),
50
+ sysfs_path: fixture_sysfs_root("cpu", "without_thermal_throttle")
51
+ }
52
+ collector = Fluent::Plugin::NodeExporter::CpuMetricsCollector.new(config)
53
+ collector.run
54
+ assert_equal([nil, nil],
55
+ [collector.cmetrics[:core_throttles_total],
56
+ collector.cmetrics[:package_throttles_total]])
57
+ end
58
+
59
+ def test_cpu_stat
60
+ config = {
61
+ scpape_interval: 1,
62
+ procfs_path: fixture_procfs_root("cpu", "with_thermal_throttle"),
63
+ sysfs_path: fixture_sysfs_root("cpu", "with_thermal_throttle")
64
+ }
65
+ collector = Fluent::Plugin::NodeExporter::CpuMetricsCollector.new(config)
66
+ stub(Etc).sysconf { 1000 }
67
+ collector.run
68
+ seconds_total = collector.cmetrics[:seconds_total]
69
+ guest_seconds_total = collector.cmetrics[:guest_seconds_total]
70
+ assert_equal([4.0, 5.0, 6.0, 2.0, 7.0, 8.0, 3.0, 1.0, 9.0, 10.0],
71
+ [seconds_total.val(["0", "idle"]),
72
+ seconds_total.val(["0", "iowait"]),
73
+ seconds_total.val(["0", "irq"]),
74
+ seconds_total.val(["0", "nice"]),
75
+ seconds_total.val(["0", "softirq"]),
76
+ seconds_total.val(["0", "steal"]),
77
+ seconds_total.val(["0", "system"]),
78
+ seconds_total.val(["0", "user"]),
79
+ guest_seconds_total.val(["0", "user"]),
80
+ guest_seconds_total.val(["0", "nice"]),
81
+ ])
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,75 @@
1
+ require "helper"
2
+ require "fluent/plugin/in_node_exporter_metrics"
3
+ require "fluent/plugin/node_exporter/cpufreq_collector"
4
+
5
+ class CpufreqColectorTest < Test::Unit::TestCase
6
+ setup do
7
+ Fluent::Test.setup
8
+ @capability = Fluent::Capability.new
9
+ end
10
+
11
+ teardown do
12
+ Fluent::Engine.stop
13
+ end
14
+
15
+ CONFIG = config_element("ROOT", "", {
16
+ "scrape_interval" => 5,
17
+ "procfs_path" => "/proc",
18
+ "sysfs_path" => "/sys"
19
+ })
20
+
21
+ def create_driver(conf = CONFIG)
22
+ Fluent::Test::Driver::Input.new(Fluent::Plugin::NodeExporterMetricsInput).configure(conf)
23
+ end
24
+
25
+ def cpufreq_available?
26
+ freq_path = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq"
27
+ Dir.exist?("/sys/devices/system/cpu/cpu0/cpufreq") and
28
+ File.exist?(freq_path) and
29
+ (File.readable?(freq_path) or @capability.have_capability?(:effective, :dac_read_search))
30
+ end
31
+
32
+ sub_test_case "cpufreq" do
33
+ data(
34
+ with: ["with_cur_freq", [
35
+ 2200000.0, 2500000.0, 2000000.0,
36
+ 2300000.0, 2400000.0, 2100000.0,
37
+ 2600000.0, 2900000.0, 2400000.0,
38
+ 2900000.0, 3000000.0, 2700000.0]],
39
+ without: ["without_cur_freq", [
40
+ nil, 2500000.0, 2000000.0,
41
+ nil, 2400000.0, 2100000.0,
42
+ 2600000.0, 2900000.0, 2400000.0,
43
+ 2900000.0, 3000000.0, 2700000.0]]
44
+ )
45
+ test "cpuinfo_cur_frequency" do |(fixture, expected)|
46
+ omit "skip assertion when cpufreq is not available" unless cpufreq_available?
47
+
48
+ config = {
49
+ sysfs_path: fixture_sysfs_root("cpufreq", fixture)
50
+ }
51
+ collector = Fluent::Plugin::NodeExporter::CpufreqMetricsCollector.new(config)
52
+ collector.run
53
+ frequency_hertz = collector.cmetrics[:frequency_hertz]
54
+ frequency_max_hertz = collector.cmetrics[:frequency_max_hertz]
55
+ frequency_min_hertz = collector.cmetrics[:frequency_min_hertz]
56
+ scaling_frequency_hertz = collector.cmetrics[:scaling_frequency_hertz]
57
+ scaling_frequency_max_hertz = collector.cmetrics[:scaling_frequency_max_hertz]
58
+ scaling_frequency_min_hertz = collector.cmetrics[:scaling_frequency_min_hertz]
59
+ assert_equal(expected,
60
+ [frequency_hertz.val(["0"]),
61
+ frequency_max_hertz.val(["0"]),
62
+ frequency_min_hertz.val(["0"]),
63
+ frequency_hertz.val(["1"]),
64
+ frequency_max_hertz.val(["1"]),
65
+ frequency_min_hertz.val(["1"]),
66
+ scaling_frequency_hertz.val(["0"]),
67
+ scaling_frequency_max_hertz.val(["0"]),
68
+ scaling_frequency_min_hertz.val(["0"]),
69
+ scaling_frequency_hertz.val(["1"]),
70
+ scaling_frequency_max_hertz.val(["1"]),
71
+ scaling_frequency_min_hertz.val(["1"]),
72
+ ])
73
+ end
74
+ end
75
+ end