This instrumentation listeners accumulates some statistics on the duration
and number of calls of a given instrumented code.

Signed-off-by: Brice Figureau <[email protected]>
---
 .../util/instrumentation/listeners/performance.rb  |   28 +++++++++++++++
 .../instrumentation/listeners/performance_spec.rb  |   37 ++++++++++++++++++++
 2 files changed, 65 insertions(+), 0 deletions(-)
 create mode 100644 lib/puppet/util/instrumentation/listeners/performance.rb
 create mode 100644 spec/unit/util/instrumentation/listeners/performance_spec.rb

diff --git a/lib/puppet/util/instrumentation/listeners/performance.rb 
b/lib/puppet/util/instrumentation/listeners/performance.rb
new file mode 100644
index 0000000..79e2162
--- /dev/null
+++ b/lib/puppet/util/instrumentation/listeners/performance.rb
@@ -0,0 +1,28 @@
+require 'monitor'
+
+Puppet::Util::Instrumentation.new_listener(:performance) do
+
+  def notify(label, event, data)
+    return if event == :start
+
+    duration = data[:finished] - data[:started]
+    samples.synchronize do
+      @samples[label] ||= { :count => 0, :max => 0, :min => 32768, :sum => 0, 
:average => 0 }
+      @samples[label][:count] += 1
+      @samples[label][:sum] += duration
+      @samples[label][:max] = [ @samples[label][:max], duration ].max
+      @samples[label][:min] = [ @samples[label][:min], duration ].min
+      @samples[label][:average] = @samples[label][:sum] / 
@samples[label][:count]
+    end
+  end
+
+  def data
+    samples.synchronize do
+      @samples.dup
+    end
+  end
+
+  def samples
+    @samples ||= {}.extend(MonitorMixin)
+  end
+end
\ No newline at end of file
diff --git a/spec/unit/util/instrumentation/listeners/performance_spec.rb 
b/spec/unit/util/instrumentation/listeners/performance_spec.rb
new file mode 100644
index 0000000..87f3f0b
--- /dev/null
+++ b/spec/unit/util/instrumentation/listeners/performance_spec.rb
@@ -0,0 +1,37 @@
+Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? 
require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") }
+
+require 'puppet/util/instrumentation'
+
+Puppet::Util::Instrumentation.init
+performance = Puppet::Util::Instrumentation.listener(:performance)
+
+describe performance do
+  before(:each) do
+    @performance = performance.new
+  end
+
+  it "should have a notify method" do
+    @performance.should respond_to(:notify)
+  end
+
+  it "should have a data method" do
+    @performance.should respond_to(:data)
+  end
+
+  it "should keep data for stop event" do
+    @performance.notify(:test, :stop, { :started => Time.at(123456789), 
:finished => Time.at(123456790)})
+    @performance.data.should == {:test=>{:average=>1.0, :count=>1, :min=>1.0, 
:max=>1.0, :sum=>1.0}}
+  end
+
+  it "should accumulate performance statistics" do
+    @performance.notify(:test, :stop, { :started => Time.at(123456789), 
:finished => Time.at(123456790)})
+    @performance.notify(:test, :stop, { :started => Time.at(123456789), 
:finished => Time.at(123456791)})
+
+    @performance.data.should == {:test=>{:average=>1.5, :count=>2, :min=>1.0, 
:max=>2.0, :sum=>3.0}}
+  end
+
+  it "should not keep data for start event" do
+    @performance.notify(:test, :start, { :started => Time.at(123456789)})
+    @performance.data.should be_empty
+  end
+end
\ No newline at end of file
-- 
1.7.2.1

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to