ref: refs/heads/jr_ntp commit d2de3a0dd755f8af939544e5a48b64fa4dfef836 Author: Duncan Mac-Vicar P <dmacvicar@suse.de> Date: Mon Sep 7 18:05:48 2009 +0200 follow collectd naming schema --- plugins/status/lib/metric.rb | 145 +++++++++++++++++++------------ plugins/status/test/unit/metric_test.rb | 61 +++++-------- 2 files changed, 114 insertions(+), 92 deletions(-) diff --git a/plugins/status/lib/metric.rb b/plugins/status/lib/metric.rb index a3b46dc..85d859f 100644 --- a/plugins/status/lib/metric.rb +++ b/plugins/status/lib/metric.rb @@ -15,29 +15,55 @@ require 'yaml' # By default the model operates in the current host, or in the # first available one, unless overriden by the :host option # -# metrics = Metric.find(:all, group => /cpu/) +# each value has an identifier based on +# host, plugin, plugin instance, type and type instance +# See http://collectd.org/wiki/index.php/Naming_schema +# +# for the naming schema of a metric +# metrics = Metric.find(:all, :plugin => /cpu/) # metrics.each do |metric| -# metric.name -# metric.group +# metric.type +# metric.type_instance +# metric.plugin +# metric.plugin_instance # metric.host # metric.data(:stop => Time.now - 5000) # end # -# class Metric COLLECTD_BASE = "/var/lib/collectd" - attr_accessor :host, :group, :name + # path to the round robin database for this value + attr_reader :path + attr_reader :host + attr_reader :plugin, :plugin_instance + attr_reader :type, :type_instance + # convenience, plugin and instance + attr_reader :plugin_full + attr_reader :type_full + + # alias for identifier + def id + identifier + end - def path - File.join(Metric.host_directory(host), group, name + '.rrd') + def identifier + [host, plugin_full, type_full].join('/') end - def id - [host, group, name].join('/') + # plugin and plugin instance ie: cpu-0 + def plugin_full + return plugin if plugin_instance.blank? + "#{plugin}-#{plugin_instance}" end + # type and type instance, ie: memory-free + def type_full + return type if type_instance.blank? + "#{type}-#{type_instance}" + end + # returns available hosts for which metrics are collected def self.available_hosts Dir.glob(File.join(COLLECTD_BASE, "*")).reject{|x| not File.directory?(x) }.map{|x| File.basename(x) } @@ -71,35 +97,45 @@ class Metric end end - # the directory where we are gathering data from - # normally is the directory corresponding to *this* - # host. If there are more than one, we take the first - # one or the one given - # - # Metrics.host_directory - # Metrics.host_directory("foo.com") - # - def self.host_directory(host=Metric.default_host) - File.join(COLLECTD_BASE, host) - end - # returns true if collectd daemon is running def self.collectd_running? ret = Scr.instance.execute(["/usr/sbin/rccollectd", "status"]) ret[:exit].zero? end - # returns the available metric groups - def self.available_groups(host=Metric.default_host) - Dir.glob(File.join(host_directory(host), '*')).reject{|x| not File.directory?(x) }.map{|x| File.basename(x) } + # + def self.plugins + Metric.find(:all).map { |x| x.plugin } end - # returns the available metrics names for a group - # that is the rrd file name without the extension - def self.available_metrics(group, host=Metric.default_host) - Dir.glob(File.join(host_directory(host), group, '*')).reject{|x| not File.file?(x) }.map{|x| File.basename(x).chomp('.rrd') } + # avaliable databases for a host + def self.rrd_files + Dir.glob(File.join(COLLECTD_BASE, '**/*.rrd')) end + + # initialize with the path to the rrdb database + def initialize(path) + @path = path + # these values can be extracted from the file but we cache + # them + @host, @plugin, @plugin_instance, @type, @type_instance = Metric.parse_file_path(path) + end + + # parses the host, plugin, plugin_instance, type and type_instance + # from the file name + def self.parse_file_path(path) + type_full = File.basename(path, '.rrd') + plugin_instance_path = File.dirname(path) + plugin_full = File.basename(plugin_instance_path) + host_path = File.dirname(plugin_instance_path) + host = File.basename(host_path) + type, type_instance = type_full.split('-', 2) + plugin, plugin_instance = plugin_full.split('-', 2) + + return host, plugin, plugin_instance, type, type_instance + end + # Finds metrics. # # Metric.find(:all) @@ -108,7 +144,7 @@ class Metric # Where id is host:group:name (whithout rrd extension) def self.find(what, opts={}) case what - when :all then find_multiple(opts) + when :all then opts.empty? ? find_all : find_multiple(opts) # in this case, the options are the first # parameter when Hash @@ -116,36 +152,37 @@ class Metric end end + # find all values + def self.find_all + ret = [] + rrd_files.each do |path| + ret << Metric.new(path) + end + ret + end + def self.find_multiple(opts) ret = [] - current_host = opts[:host] || default_host - available_hosts.each do |host| - # if host is specified, only use that - # host - next if host != current_host - available_groups(current_host).each do |group| - # filter by group - case opts[:group] - when Regexp - next if not group =~ opts[:group] - when String - next if group != opts[:group] - end - available_metrics(group, current_host).each do |metric_name| - # filter by name - case opts[:name] - when Regexp then next if not metric_name =~ opts[:name] - when String then next if metric_name != opts[:name] - end - # instantiate the object - metric = Metric.new - metric.host = current_host - metric.name = metric_name - metric.group = group - ret << metric + # think how to factor this out + opts[:host] = default_host if not opts.has_key?(:host) + + all = Metric.find(:all) + all.each do |metric| + matched = true + # match each attribute passed in opts + opts.each do |key, val| + raise "Unknown attribute #{key}" if not metric.respond_to?(key) + # if the val is a regexp we do different matching + if val.is_a?(Regexp) + matched = false if not metric.send(key) =~ val + else + matched = false if metric.send(key) != val end end + # go to next value if this does not match + next if not matched + ret << metric end ret end diff --git a/plugins/status/test/unit/metric_test.rb b/plugins/status/test/unit/metric_test.rb index 52fc8b5..6ae1a4e 100644 --- a/plugins/status/test/unit/metric_test.rb +++ b/plugins/status/test/unit/metric_test.rb @@ -12,37 +12,22 @@ class MetricTest < ActiveSupport::TestCase def setup # standard setup - Metric.stubs(:this_hostname).returns('myhost.domain.de') + Metric.stubs(:this_hostname).returns('myhost.domain.de') Metric.stubs(:available_hosts).returns(['foo.com', 'myhost.domain.de']) - Metric.stubs(:available_groups).with('myhost.domain.de').returns(['memory', 'cpu-1', 'cpu-2', 'interface']) - Metric.stubs(:available_metrics).with('memory', 'myhost.domain.de').returns(['memory-free']) - Metric.stubs(:available_metrics).with('cpu-1', 'myhost.domain.de').returns(['cpudata1', 'cpudata2']) - Metric.stubs(:available_metrics).with('cpu-2', 'myhost.domain.de').returns(['cpudata1']) - Metric.stubs(:available_metrics).with('interface', 'myhost.domain.de').returns(['packets']) - # in total 5 metrics, 4 groups, 2 hosts - - + Metric.stubs(:rrd_files).returns(['/var/lib/collectd/foo.com/cpu-0/cppudata-1.rrd', '/var/lib/collectd/myhost.domain.de/memory/memory-free.rrd', '/var/lib/collectd/myhost.domain.de/cpu-1/cpudata-1.rrd', '/var/lib/collectd/myhost.domain.de/cpu-1/cpudata-2.rrd', '/var/lib/collectd/myhost.domain.de/cpu-2/cpudata-1.rrd', '/var/lib/collectd/myhost.domain.de/interface/packets.rrd', '/var/lib/collectd/myhost.domain.de/interface/some-0.rrd']) end def teardown end - def test_host_directory + def test_default_host # if only one host data is available, then that one should be # the one used for the data directory Metric.stubs(:this_hostname).returns(nil) assert_equal 'foo.com', Metric.default_host - assert_equal File.join(Metric::COLLECTD_BASE, 'foo.com'), Metric.host_directory - # if our hostname is in the available list, that one should be the default host + Metric.stubs(:this_hostname).returns('myhost.domain.de') assert_equal 'myhost.domain.de', Metric.default_host - assert_equal File.join(Metric::COLLECTD_BASE, 'myhost.domain.de'), Metric.host_directory - - # if no host data is available, no base_directory - Metric.stubs(:available_hosts).returns([]) - assert_raise RuntimeError do - Metric.host_directory - end end def test_parse_rrdtool_output @@ -52,7 +37,7 @@ class MetricTest < ActiveSupport::TestCase Metric.stubs(:run_rrdtool).with('/var/lib/collectd/myhost.domain.de/memory/memory-free.rrd', :start => start, :stop => stop).returns(File.open(test_data('rrdtool-memory-free.txt')).read) Metric.stubs(:run_rrdtool).with('/var/lib/collectd/myhost.domain.de/interface/packets.rrd', :start => start, :stop => stop).returns(File.open(test_data('rrdtool-packets.txt')).read) - ret = Metric.find(:all, :group => /memory/, :name => 'memory-free') + ret = Metric.find(:all, :plugin => /memory/, :type => 'memory', :type_instance => 'free') memory = ret.first expected = { "value"=> @@ -70,7 +55,7 @@ class MetricTest < ActiveSupport::TestCase assert_equal expected, memory.data(:start => start, :stop => stop) - ret = Metric.find(:all, :group => /interface/, :name => 'packets') + ret = Metric.find(:all, :plugin => /interface/, :type => 'packets') packets = ret.first expected = {"tx"=> {"1252075780"=>"4.2576000000e+02", @@ -102,41 +87,41 @@ class MetricTest < ActiveSupport::TestCase def test_finders ret = Metric.find(:all) - assert_equal 5, ret.size - assert ret.map{|x| x.group}.include?('cpu-1') - assert ret.map{|x| x.group}.include?('memory') - assert ret.map{|x| x.group}.include?('interface') + assert_equal 7, ret.size + assert ret.map{|x| x.plugin_full}.include?('cpu-1') + assert ret.map{|x| x.plugin}.include?('memory') + assert ret.map{|x| x.plugin}.include?('interface') - ret = Metric.find(:all, :group => 'memory') + ret = Metric.find(:all, :plugin => 'memory') assert_equal 1, ret.size - assert_equal 'memory', ret.first.group - assert_equal 'memory-free', ret.first.name + assert_equal 'memory', ret.first.plugin + assert_equal 'memory-free', ret.first.type_full assert_equal 'myhost.domain.de', ret.first.host # should produce same result - ret = Metric.find(:all, :group => /memory/) + ret = Metric.find(:all, :plugin_full => /memory/) assert_equal 1, ret.size - ret = Metric.find(:all, :group => /memory/, :name => 'boooh') + ret = Metric.find(:all, :plugin_full => /memory/, :type_full => 'boooh') assert_equal 0, ret.size - ret = Metric.find(:all, :group => /memory/, :name => 'memory-free') + ret = Metric.find(:all, :plugin_full => /memory/, :type_full => 'memory-free') assert_equal 1, ret.size # test attributes assert_equal '/var/lib/collectd/myhost.domain.de/memory/memory-free.rrd', ret.first.path assert_equal 'myhost.domain.de/memory/memory-free', ret.first.id - ret = Metric.find(:all, :group => /meemory/) + ret = Metric.find(:all, :plugin_full => /meemory/) assert_equal 0, ret.size - ret = Metric.find(:all, :group => 'meemory') + ret = Metric.find(:all, :plugin_full => 'meemory') assert_equal 0, ret.size # using a regexp - ret = Metric.find(:all, :group => /cpu/) - assert ret.map{ |x| x.group }.include?('cpu-1') - assert ret.map{ |x| x.group }.include?('cpu-2') - assert ret.map{ |x| x.name }.include?('cpudata1') - assert ret.map{ |x| x.name }.include?('cpudata2') + ret = Metric.find(:all, :plugin_full => /cpu/) + assert ret.map{ |x| x.plugin_full }.include?('cpu-1') + assert ret.map{ |x| x.plugin_full }.include?('cpu-2') + assert ret.map{ |x| x.type_full }.include?('cpudata-1') + assert ret.map{ |x| x.type_full }.include?('cpudata-2') assert_equal 3, ret.size end -- To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org For additional commands, e-mail: yast-commit+help@opensuse.org