From f426d16e5734d21b376f8a3fb1cd44658794a677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20B=C3=B6hm?= Date: Wed, 12 Sep 2012 12:27:19 +0200 Subject: [PATCH 1/3] add support for derivative metrics A derivative metric is like a meter but accepts an absolute counter as input. This is useful for metrics like bytes sent over the network or cpu cycles which are generally monotonically increasing counters and therefore need to be derived from the previous sample to get a useful rate/s value. --- lib/metriks.rb | 5 ++++- lib/metriks/derive.rb | 13 +++++++++++++ lib/metriks/registry.rb | 18 +++++++++++++++++- 3 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 lib/metriks/derive.rb diff --git a/lib/metriks.rb b/lib/metriks.rb index 694ab97..90675c1 100644 --- a/lib/metriks.rb +++ b/lib/metriks.rb @@ -1,4 +1,3 @@ - module Metriks VERSION = '0.9.9.1' @@ -22,6 +21,10 @@ def self.meter(name) Metriks::Registry.default.meter(name) end + def self.derive(name) + Metriks::Registry.default.derive(name) + end + def self.histogram(name) Metriks::Registry.default.histogram(name) end diff --git a/lib/metriks/derive.rb b/lib/metriks/derive.rb new file mode 100644 index 0000000..ae9d1a7 --- /dev/null +++ b/lib/metriks/derive.rb @@ -0,0 +1,13 @@ +require 'atomic' + +require 'metriks/ewma' + +module Metriks + class Derive < Metriks::Meter + def mark(val = 1) + @last ||= Atomic.new(val) + last = @last.swap(val) + super(last > val ? val : val - last) + end + end +end diff --git a/lib/metriks/registry.rb b/lib/metriks/registry.rb index 5decd9f..68b3985 100644 --- a/lib/metriks/registry.rb +++ b/lib/metriks/registry.rb @@ -2,6 +2,7 @@ require 'metriks/timer' require 'metriks/utilization_timer' require 'metriks/meter' +require 'metriks/derive' module Metriks # Public: A collection of metrics @@ -86,6 +87,21 @@ def meter(name) add_or_get(name, Metriks::Meter) end + # Public: Fetch or create a new derivative metric. Derivatives are a meter + # that tracks throughput by calculating the derivative to the previous + # value. + # + # name - The String name of the metric to define or fetch + # + # Examples + # + # registry.derive('network.bytes') + # + # Returns the Metricks::Derive identified by the name. + def derive(name) + add_or_get(name, Metriks::Derive) + end + # Public: Fetch or create a new timer metric. Timers provide the means to # time the execution of a method including statistics on the number of # invocations, average length of time, throughput. @@ -188,4 +204,4 @@ def add_or_get(name, klass, &create_metric) end end end -end \ No newline at end of file +end From d2baf7018eb21e251f9460981c0a266098898541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20B=C3=B6hm?= Date: Wed, 12 Sep 2012 13:02:37 +0200 Subject: [PATCH 2/3] update require statement --- lib/metriks/derive.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/metriks/derive.rb b/lib/metriks/derive.rb index ae9d1a7..75a8c48 100644 --- a/lib/metriks/derive.rb +++ b/lib/metriks/derive.rb @@ -1,6 +1,6 @@ require 'atomic' -require 'metriks/ewma' +require 'metriks/meter' module Metriks class Derive < Metriks::Meter From 4a9a9e41ae86bddc232d741995d1df6a8846ea59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20B=C3=B6hm?= Date: Wed, 12 Sep 2012 13:12:38 +0200 Subject: [PATCH 3/3] add unit test for derive --- test/derive_test.rb | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 test/derive_test.rb diff --git a/test/derive_test.rb b/test/derive_test.rb new file mode 100644 index 0000000..24a7f27 --- /dev/null +++ b/test/derive_test.rb @@ -0,0 +1,32 @@ +require 'test_helper' + +require 'metriks/derive' + +class DeriveTest < Test::Unit::TestCase + include ThreadHelper + + def setup + @meter = Metriks::Derive.new + end + + def teardown + @meter.stop + end + + def test_meter + @meter.mark(100) + @meter.mark(150) + + assert_equal 50, @meter.count + end + + def test_one_minute_rate + @meter.mark(1000) + @meter.mark(2000) + + # Pretend it's been 5 seconds + @meter.tick + + assert_equal 200, @meter.one_minute_rate + end +end