fluent-plugin-node-exporter-metrics 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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