From 4af4c45fcc4d186180d0df4864be471a2394b647 Mon Sep 17 00:00:00 2001 From: ianzhang Date: Wed, 20 Apr 2011 01:33:20 -0700 Subject: [PATCH 1/2] added console reporter --- lib/ruby-metrics/console_reporter.rb | 100 ++++++++++++++++++++++++++ lib/ruby-metrics/instruments/meter.rb | 2 +- 2 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 lib/ruby-metrics/console_reporter.rb diff --git a/lib/ruby-metrics/console_reporter.rb b/lib/ruby-metrics/console_reporter.rb new file mode 100644 index 0000000..7ccc4bc --- /dev/null +++ b/lib/ruby-metrics/console_reporter.rb @@ -0,0 +1,100 @@ +require File.join(File.dirname(__FILE__), 'logging') +require File.join(File.dirname(__FILE__), 'instruments') +require File.join(File.dirname(__FILE__), 'time_units') + +module Metrics + class ConsoleReporter + include Logging + include Instruments::TypeMethods + + attr_reader :instruments + + def initialize(out = STDOUT) + logger.debug "Initializing Reporter..." + @instruments = Metrics::Instruments + @out = out + end + + def start(period = 10) + start_reporter_daemon_thread(period) + end + + protected + def start_reporter_daemon_thread(period) + logger.debug "Creating Metrics console reporter daemon thread." + @reporter_daemon_thread = Thread.new do + begin + loop do + start_time = Time.now + start_time_str = start_time.strftime("%m/%d/%Y %X ") + @out.print start_time_str + (80-start_time_str.length-1).times { @out.print('=') } + @out.puts + + @instruments.registered.each do |name, metric| + @out.puts "Name: #{name}, Type: #{metric.class.to_s.gsub(/.+::/, "")}" + if metric.instance_of? Instruments::Gauge + print_gauge metric + elsif metric.instance_of? Instruments::Counter + print_counter metric + elsif metric.is_a? Instruments::Histogram + print_histogram metric + elsif metric.instance_of? Instruments::Meter + print_metered metric + elsif metric.instance_of? Instruments::Timer + print_timer metric + end + end + + @out.puts + @out.flush + sleep(period) + end + rescue Exception => e + logger.error "Error in worker thread: #{e.class.name}: #{e}\n #{e.backtrace.join("\n ")}" + end # begin + end # thread new + end + + def print_gauge(gauge) + @out.puts(" value = #{gauge.get}") + end + + def print_counter(counter) + @out.puts(" count = #{counter}") + end + + def print_metered(meter) + @out.puts(" count = #{meter.count}") + @out.puts(" mean rate = #{meter.mean_rate}") + @out.puts(" 1-minute rate = #{meter.one_minute_rate}") + @out.puts(" 5-minute rate = #{meter.five_minute_rate}") + @out.puts(" 15-minute rate = #{meter.fifteen_minute_rate}") + end + + def print_histogram(histogram) + percentiles = histogram.quantiles([0.5, 0.75, 0.95, 0.98, 0.99, 0.999]) + @out.puts(" min = #{histogram.min}") + @out.puts(" max = #{histogram.max}") + @out.puts(" mean = #{histogram.mean}") + @out.puts(" stddev = #{histogram.std_dev}") + percentiles.each do |name, percentile| + @out.puts(" #{name} <= #{percentile}") + end + end + + def print_timer(timer) + print_metered(timer); + + percentiles = timer.quantiles([0.5, 0.75, 0.95, 0.98, 0.99, 0.999]); + @out.puts(" min = #{timer.min}") + @out.puts(" max = #{timer.max}") + @out.puts(" mean = #{timer.mean}") + @out.puts(" stddev = #{timer.std_dev}") + percentiles.each do |name, percentile| + @out.puts(" #{name} <= #{percentile}") + end + end + + end +end \ No newline at end of file diff --git a/lib/ruby-metrics/instruments/meter.rb b/lib/ruby-metrics/instruments/meter.rb index 896557e..90d6550 100644 --- a/lib/ruby-metrics/instruments/meter.rb +++ b/lib/ruby-metrics/instruments/meter.rb @@ -74,7 +74,7 @@ def fifteen_minute_rate(rate_unit = :seconds) convert_to_ns @fifteen_minute_rate, rate_unit end - def mean_rate(rate_unit = seconds) + def mean_rate(rate_unit = :seconds) count = @count if count == 0 return 0.0; From 3cd4324095fc6d1c6bcd4085a5fec003bb083128 Mon Sep 17 00:00:00 2001 From: ianzhang Date: Thu, 21 Apr 2011 13:01:21 -0700 Subject: [PATCH 2/2] added reporter spec file --- .bundle/config | 2 ++ lib/ruby-metrics.rb | 1 + lib/ruby-metrics/console_reporter.rb | 33 +++++++++-------- spec/console_reporter_spec.rb | 54 ++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 15 deletions(-) create mode 100644 .bundle/config create mode 100644 spec/console_reporter_spec.rb diff --git a/.bundle/config b/.bundle/config new file mode 100644 index 0000000..8ebbe30 --- /dev/null +++ b/.bundle/config @@ -0,0 +1,2 @@ +--- +BUNDLE_DISABLE_SHARED_GEMS: "1" diff --git a/lib/ruby-metrics.rb b/lib/ruby-metrics.rb index f008e5b..a4a3397 100644 --- a/lib/ruby-metrics.rb +++ b/lib/ruby-metrics.rb @@ -20,3 +20,4 @@ def logger require File.join(File.dirname(__FILE__), 'ruby-metrics', 'agent') +require File.join(File.dirname(__FILE__), 'ruby-metrics', 'console_reporter') diff --git a/lib/ruby-metrics/console_reporter.rb b/lib/ruby-metrics/console_reporter.rb index 7ccc4bc..3570682 100644 --- a/lib/ruby-metrics/console_reporter.rb +++ b/lib/ruby-metrics/console_reporter.rb @@ -31,20 +31,7 @@ def start_reporter_daemon_thread(period) (80-start_time_str.length-1).times { @out.print('=') } @out.puts - @instruments.registered.each do |name, metric| - @out.puts "Name: #{name}, Type: #{metric.class.to_s.gsub(/.+::/, "")}" - if metric.instance_of? Instruments::Gauge - print_gauge metric - elsif metric.instance_of? Instruments::Counter - print_counter metric - elsif metric.is_a? Instruments::Histogram - print_histogram metric - elsif metric.instance_of? Instruments::Meter - print_metered metric - elsif metric.instance_of? Instruments::Timer - print_timer metric - end - end + print_instruments @out.puts @out.flush @@ -56,6 +43,23 @@ def start_reporter_daemon_thread(period) end # thread new end + def print_instruments + @instruments.registered.each do |name, metric| + @out.puts "Name: #{name}, Type: #{metric.class.to_s.gsub(/.+::/, "")}" + if metric.is_a? Instruments::Gauge + print_gauge(metric) + elsif metric.is_a? Instruments::Counter + print_counter(metric) + elsif metric.is_a? Instruments::Histogram + print_histogram(metric) + elsif metric.is_a? Instruments::Meter + print_metered(metric) + elsif metric.is_a? Instruments::Timer + print_timer(metric) + end + end + end + def print_gauge(gauge) @out.puts(" value = #{gauge.get}") end @@ -85,7 +89,6 @@ def print_histogram(histogram) def print_timer(timer) print_metered(timer); - percentiles = timer.quantiles([0.5, 0.75, 0.95, 0.98, 0.99, 0.999]); @out.puts(" min = #{timer.min}") @out.puts(" max = #{timer.max}") diff --git a/spec/console_reporter_spec.rb b/spec/console_reporter_spec.rb new file mode 100644 index 0000000..0b0194b --- /dev/null +++ b/spec/console_reporter_spec.rb @@ -0,0 +1,54 @@ +require 'spec_helper.rb' + +describe Metrics::ConsoleReporter do + before :each do + out = File.new('/dev/null', 'w') + @reporter = Metrics::ConsoleReporter.new(out) + end + + it "should call the get method for gauge" do + gauge = Metrics::Instruments::Gauge.new do + "test" + end + Metrics::Instruments::Gauge.stub!(:new).and_return gauge + gauge.should_receive(:get) + @reporter.gauge :test_gauge do + "test" + end + @reporter.instance_eval { print_instruments } + end + + it "should call the to_s method for counter" do + counter = Metrics::Instruments::Counter.new + Metrics::Instruments::Counter.stub!(:new).and_return counter + counter.should_receive(:to_s) + @reporter.counter(:test_counter) + @reporter.instance_eval { print_instruments } + end + + it "should call the count, mean_rate, one_minute_rate, five_minute_rate, fifteen_minute_rate methods for meter" do + Thread.stub!(:new).and_return nil + meter = Metrics::Instruments::Meter.new + Metrics::Instruments::Meter.stub!(:new).and_return meter + meter.should_receive(:count) + meter.should_receive(:mean_rate) + meter.should_receive(:one_minute_rate) + meter.should_receive(:five_minute_rate) + meter.should_receive(:fifteen_minute_rate) + @reporter.meter(:test_meter) + @reporter.instance_eval { print_instruments } + end + + it "should call the min, max, mean, std_dev, quantiles methods for histogram" do + uniform_histogram = Metrics::Instruments::UniformHistogram.new + Metrics::Instruments::UniformHistogram.stub!(:new).and_return uniform_histogram + uniform_histogram.stub!(:quantiles).and_return [] + uniform_histogram.should_receive(:quantiles) + uniform_histogram.should_receive(:min) + uniform_histogram.should_receive(:max) + uniform_histogram.should_receive(:mean) + uniform_histogram.should_receive(:std_dev) + @reporter.uniform_histogram(:test_histogram) + @reporter.instance_eval { print_instruments } + end +end \ No newline at end of file