Skip to content

Commit

Permalink
Make Collector a singleton class
Browse files Browse the repository at this point in the history
  • Loading branch information
zorab47 committed Nov 17, 2011
1 parent d356834 commit 24f850d
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 112 deletions.
2 changes: 1 addition & 1 deletion Rakefile
Expand Up @@ -9,6 +9,6 @@ task :watchr do
end

task :environment do
require 'lib/metrics_collector'
require 'metrics_collector'
require 'spec/sample_app'
end
4 changes: 1 addition & 3 deletions lib/metrics_collector.rb
@@ -1,6 +1,4 @@
require 'set'

require 'metrics_collector/metric'
require 'metrics_collector/collector'
require 'metrics_collector/metric'
require 'metrics_collector/metric_snapshot'
require 'metrics_collector/model_additions'
25 changes: 16 additions & 9 deletions lib/metrics_collector/collector.rb
@@ -1,21 +1,28 @@
require 'set'
require 'singleton'

module MetricsCollector
class Collector
@@monitored_classes = Set.new
attr_reader :metrics

def self.monitor(klass)
@@monitored_classes << klass
def initialize
@metrics = Set.new
end

def self.monitored_classes
@@monitored_classes
def monitor(metric)
@metrics << metric
end

def self.clear
@@monitored_classes = Set.new
def clear
@metrics.clear
end

def self.collect
monitored_classes.collect { |klass| klass.metrics.values }.flatten.collect { |metric| metric.snapshot}
def collect
metrics.collect { |metric| metric.snapshot }
end
end

class SingletonCollector < Collector
include Singleton
end
end
4 changes: 4 additions & 0 deletions lib/metrics_collector/metric_snapshot.rb
Expand Up @@ -8,6 +8,10 @@ def initialize(name, value)
self.value = value
end

def to_s
"#{name}: #{value}"
end

end
end

11 changes: 2 additions & 9 deletions lib/metrics_collector/model_additions.rb
@@ -1,15 +1,8 @@
module MetricsCollector
module ModelAdditions
module ClassMethods
@@metrics = Hash.new

def metric(name, &block)
MetricsCollector::Collector.monitor(self)
@@metrics[name] = MetricsCollector::Metric.new(self, name, &block)
end

def metrics
@@metrics
def metric(name, collector = MetricsCollector::SingletonCollector.instance, &block)
collector.monitor(MetricsCollector::Metric.new(self, name, &block))
end
end
end
Expand Down
3 changes: 2 additions & 1 deletion lib/tasks/metrics_collector.rake
Expand Up @@ -2,7 +2,8 @@ namespace :metrics_collector do

desc "Collect all defined metrics"
task :collect => [:environment] do
puts MetricsCollector::Collector.collect.inspect
snapshots = MetricsCollector::SingletonCollector.instance.collect
puts snapshots.collect(&:to_s)
end

end
50 changes: 40 additions & 10 deletions spec/metrics_collector/collector_spec.rb
@@ -1,20 +1,50 @@
require "spec_helper"

describe MetricsCollector::Collector do
subject { MetricsCollector::Collector }

before do
MetricsCollector::Collector.clear
@collector = MetricsCollector::Collector.new
end

subject { @collector }

it "adds metrics to monitor" do
metric = double("metric")
subject.monitor(metric)
subject.metrics.should include(metric)
end

it "only adds a single entry of each metric" do
metric = double("metric")
subject.monitor(metric)
subject.monitor(metric)
subject.metrics.size.should eq(1)
end

it "adds classes to monitor" do
subject.monitor(Project)
subject.monitored_classes.should include(Project)
context "with a metric" do
before do
@metric = double("metric")
@collector.monitor(@metric)
end

it "clears all metrics" do
subject.clear
subject.metrics.should be_empty
end

it "collects metric snapshots" do
snapshot = double("snapshot")
@metric.should_receive(:snapshot).and_return(snapshot)
subject.collect.should include(snapshot)
end
end
end

describe MetricsCollector::SingletonCollector do
it "behaves like a singleton" do
MetricsCollector::SingletonCollector.instance.should be(MetricsCollector::SingletonCollector.instance)
end

it "only adds a single entry of each class" do
subject.monitor(Project)
subject.monitor(Project)
subject.monitored_classes.size.should eq(1)
it "does not directly allow instanciation" do
lambda { MetricsCollector::SingletonCollector.new }.should raise_error(NoMethodError)
end
end
56 changes: 11 additions & 45 deletions spec/metrics_collector/metric_snapshot_spec.rb
@@ -1,57 +1,23 @@
require "spec_helper"

describe MetricsCollector::MetricSnapshot do
before(:all) do
MetricsCollector::Collector.clear

Project.metrics.clear

class Project
@@count = 0

metric :counter do
@@count += 1
end

def self.reset
@@count = 0
end
end
before do
@snapshot = MetricsCollector::MetricSnapshot.new(:name, 1.0)
end

context "with a class monitored" do
before(:each) do
Project.reset
end

context "collecting the metrics" do
let(:collection) { MetricsCollector::Collector.collect }
subject { collection }

it "has a collection of snapshots" do
subject.should_not be_empty
end
let(:snapshot) { @snapshot }

it "contains only one metric" do
subject.size.should == 1
end

context "with a metric" do
subject { collection.first }

it "contains a MetricSnapshot" do
subject.should be_a(MetricsCollector::MetricSnapshot)
end
it "has a name" do
snapshot.name.should eq(:name)
end

it "contains a snapshot for Project counter" do
subject.name.should eq(:counter)
end
it "has a value" do
snapshot.value.should eq(1.0)
end

it "contains a reading from Project counter" do
subject.value.should == 1
end
end
end
it "outputs as a formatted string" do
snapshot.to_s.should eq("name: 1.0")
end

end
1 change: 1 addition & 0 deletions spec/metrics_collector/metric_spec.rb
Expand Up @@ -26,6 +26,7 @@
end

context "when taking a snapshot" do

subject { metric.snapshot }

it "creates a snapshot" do
Expand Down
40 changes: 6 additions & 34 deletions spec/metrics_collector/model_additions_spec.rb
@@ -1,49 +1,21 @@
require "spec_helper"

describe MetricsCollector::ModelAdditions do
subject { Project }

it "can define metrics on models" do
subject.should respond_to(:metric)
Project.should respond_to(:metric)
end

context "with a metric defined" do
before do
subject.class_eval do
metric :count do
0.0
end
end
end

it "adds that metric to the metric list" do
subject.metrics.should_not be_empty
end

it "adds the class to Collector" do
MetricsCollector::Collector.monitored_classes.should include(Project)
end

it "saves the block as a metric instance" do
subject.metrics[:count].should be_kind_of(MetricsCollector::Metric)
end
end
context "when defining a metric" do
it "is added to the collector" do
collector = double("collector")
collector.should_receive(:monitor).with(an_instance_of(MetricsCollector::Metric))

context "with multiple metrics defined" do
before do
Project.class_eval do
metric :count do
0.0
end

metric :usage do
metric(:count, collector) do
0.0
end
end
end

it "contains multiple unique metrics" do
subject.metrics.size.should == 2
end
end
end

0 comments on commit 24f850d

Please sign in to comment.