diff --git a/lib/fluent/plugin_helper/metrics.rb b/lib/fluent/plugin_helper/metrics.rb index 2b31795126..f3fdb8afe4 100644 --- a/lib/fluent/plugin_helper/metrics.rb +++ b/lib/fluent/plugin_helper/metrics.rb @@ -28,8 +28,11 @@ module PluginHelper module Metrics include Fluent::SystemConfig::Mixin + attr_reader :_metrics # For tests. + def initialize super + @_metrics_started = false @_metrics = {} # usage => metrics_state end @@ -68,7 +71,52 @@ def metrics_create(namespace: "fluentd", subsystem: "metrics", name:, help_text: metrics end + def metrics_operate(method_name, &block) + @_metrics.each_pair do |key, m| + begin + block.call(s) if block_given? + m.__send__(method_name) + rescue => e + log.error "unexpected error while #{method_name}", key: key, metrics: m, error: e + end + end + end + + def start + super + + metrics_operate(:start) + @_metrics_started = true + end + + def stop + super + # timer stops automatically in super + metrics_operate(:stop) + end + + def before_shutdown + metrics_operate(:before_shutdown) + super + end + + def shutdown + metrics_operate(:shutdown) + super + end + + def after_shutdown + metrics_operate(:after_shutdown) + super + end + + def close + metrics_operate(:close) + super + end + def terminate + metrics_operate(:terminate) @_metrics = {} super end diff --git a/test/plugin_helper/test_metrics.rb b/test/plugin_helper/test_metrics.rb new file mode 100644 index 0000000000..77ee50c24b --- /dev/null +++ b/test/plugin_helper/test_metrics.rb @@ -0,0 +1,128 @@ +require_relative '../helper' +require 'fluent/plugin_helper/metrics' +require 'fluent/plugin/base' + +class MetricsTest < Test::Unit::TestCase + class Dummy < Fluent::Plugin::TestBase + helpers :metrics + def configure(conf) + super + end + end + + setup do + @d = nil + end + + teardown do + if @d + @d.stop unless @d.stopped? + @d.shutdown unless @d.shutdown? + @d.close unless @d.closed? + @d.terminate unless @d.terminated? + end + end + + test 'can be initialized without any metrics at first' do + d = Dummy.new + assert_equal 0, d._metrics.size + end + + test 'can be configured' do + d1 = Dummy.new + assert_nothing_raised do + d1.configure(config_element()) + end + assert d1.plugin_id + assert d1.log + end + + test 'creates metrics instances' do + d = Dummy.new + d.configure(config_element()) + i = d.metrics_create(namespace: "fluentd_test", subsystem: "unit-test", name: "metrics1", help_text: "metrics testing") + assert{ i.is_a?(Fluent::Plugin::LocalMetrics) } + assert_true i.has_methods_for_counter + assert_false i.has_methods_for_gauge + + d = Dummy.new + d.configure(config_element()) + i = d.metrics_create(namespace: "fluentd_test", subsystem: "unit-test", name: "metrics2", help_text: "metrics testing", prefer_gauge: true) + assert{ i.is_a?(Fluent::Plugin::LocalMetrics) } + assert_false i.has_methods_for_counter + assert_true i.has_methods_for_gauge + end + + test 'calls lifecycle methods for all plugin instances via owner plugin' do + @d = d = Dummy.new + d.configure(config_element()) + i1 = d.metrics_create(namespace: "fluentd_test", subsystem: "unit-test", name: "metrics1", help_text: "metrics testing") + i2 = d.metrics_create(namespace: "fluentd_test", subsystem: "unit-test", name: "metrics2", help_text: "metrics testing", prefer_gauge: true) + i3 = d.metrics_create(namespace: "fluentd_test", subsystem: "unit-test", name: "metrics3", help_text: "metrics testing") + d.start + + assert i1.started? + assert i2.started? + assert i3.started? + + assert !i1.stopped? + assert !i2.stopped? + assert !i3.stopped? + + d.stop + + assert i1.stopped? + assert i2.stopped? + assert i3.stopped? + + assert !i1.before_shutdown? + assert !i2.before_shutdown? + assert !i3.before_shutdown? + + d.before_shutdown + + assert i1.before_shutdown? + assert i2.before_shutdown? + assert i3.before_shutdown? + + assert !i1.shutdown? + assert !i2.shutdown? + assert !i3.shutdown? + + d.shutdown + + assert i1.shutdown? + assert i2.shutdown? + assert i3.shutdown? + + assert !i1.after_shutdown? + assert !i2.after_shutdown? + assert !i3.after_shutdown? + + d.after_shutdown + + assert i1.after_shutdown? + assert i2.after_shutdown? + assert i3.after_shutdown? + + assert !i1.closed? + assert !i2.closed? + assert !i3.closed? + + d.close + + assert i1.closed? + assert i2.closed? + assert i3.closed? + + assert !i1.terminated? + assert !i2.terminated? + assert !i3.terminated? + + d.terminate + + assert i1.terminated? + assert i2.terminated? + assert i3.terminated? + end +end