librato-metrics 0.6.0.pre2 → 0.6.0.pre3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -40,9 +40,9 @@ Make sure you have [an account for Metrics](https://metrics.librato.com/) and th
40
40
 
41
41
  Librato::Metrics.authenticate 'email', 'api_key'
42
42
 
43
- ## Sending Metrics
43
+ ## Sending Measurements
44
44
 
45
- If you are sending very many metrics or sending them very often, it will be much higher performance to bundle them up together to reduce your request volume. Use `Queue` for this.
45
+ If you are sending very many measurements or sending them very often, it will be much higher performance to bundle them up together to reduce your request volume. Use `Queue` for this.
46
46
 
47
47
  Queue up a simple gauge metric named `temperature`:
48
48
 
@@ -65,15 +65,46 @@ Save all queued metrics:
65
65
 
66
66
  queue.submit
67
67
 
68
+ ## Aggregate Measurements
69
+
70
+ If you are measuring something very frequently e.g. per-request in a web application (order mS) you may not want to send each individual measurement, but rather periodically send a [single aggregate measurement](http://dev.librato.com/v1/post/metrics#gauge_specific), spanning multiple seconds or even minutes. Use an `Aggregator` for this.
71
+
72
+ Aggregate a simple gauge metric named `response_latency`:
73
+
74
+ aggregator = Librato::Metrics::Aggregator.new
75
+ aggregator.add :response_latency => 85.0
76
+ aggregator.add :response_latency => 100.5
77
+ aggregator.add :response_latency => 150.2
78
+ aggregator.add :response_latency => 90.1
79
+ aggregator.add :response_latency => 92.0
80
+
81
+ Which would result in a gauge measurement like:
82
+
83
+ {:name => "response_latency", :count => 5, :sum => 517.8, :min => 85.0, :max => 150.2}
84
+
85
+ You can specify a source during aggregate construction:
86
+
87
+ aggregator = Librato::Metrics::Aggregator.new(:source => 'foobar')
88
+
89
+ You can aggregate multiple metrics at once:
90
+
91
+ aggregator.add :app_latency => 35.2, :db_latency => 120.7
92
+
93
+ Send the current aggregated metrics to Metrics:
94
+
95
+ aggregator.submit
96
+
68
97
  ## Benchmarking
69
98
 
70
- If you have operations in your application you want to record execution time for, you can use the `#time` method:
99
+ If you have operations in your application you want to record execution time for, both `Queue` and `Aggregator` support the `#time` method:
71
100
 
72
- queue.time :my_measurement do
101
+ aggregator.time :my_measurement do
73
102
  # do work...
74
103
  end
75
104
 
76
- If you need extra attributes for the measurement, simply add them on:
105
+ The difference between the two is that `Queue` submits each timing measurement individually, while `Aggregator` submits a single timing measurement spanning all executions.
106
+
107
+ If you need extra attributes for a `Queue` timing measurement, simply add them on:
77
108
 
78
109
  queue.time :my_measurement, :source => 'app1' do
79
110
  # do work...
@@ -162,4 +193,4 @@ These are features we expect to add in future versions, roughly in the order of
162
193
 
163
194
  ## Copyright
164
195
 
165
- Copyright (c) 2011-2012 [Librato Inc.](http://librato.com) See LICENSE for details.
196
+ Copyright (c) 2011-2012 [Librato Inc.](http://librato.com) See LICENSE for details.
@@ -4,6 +4,7 @@ $:.unshift(File.dirname(__FILE__)) unless
4
4
  require 'base64'
5
5
  require 'multi_json'
6
6
 
7
+ require 'metrics/aggregator'
7
8
  require 'metrics/client'
8
9
  require 'metrics/collection'
9
10
  require 'metrics/connection'
@@ -0,0 +1,68 @@
1
+ require 'aggregate'
2
+ require 'metrics/processor'
3
+
4
+ module Librato
5
+ module Metrics
6
+
7
+ class Aggregator
8
+ include Processor
9
+
10
+ attr_reader :source
11
+
12
+ def initialize(options={})
13
+ @aggregated = {}
14
+ @client = options[:client] || Librato::Metrics.client
15
+ @source = options[:source]
16
+ end
17
+
18
+ # Add a metric entry to the metric set:
19
+ #
20
+ # @param Hash metrics metrics to add
21
+ def add(args)
22
+ args.each do |k, v|
23
+ value = v.respond_to?(:each) ? v[:value] : v
24
+
25
+ @aggregated[k] ||= Aggregate.new
26
+ @aggregated[k] << value
27
+ end
28
+ end
29
+
30
+ # Returns true if aggregate contains no measurements
31
+ #
32
+ # @return Boolean
33
+ def empty?
34
+ @aggregated.empty?
35
+ end
36
+
37
+ # Remove all queued metrics
38
+ #
39
+ def flush
40
+ @aggregated = {}
41
+ end
42
+ alias :clear :flush
43
+
44
+ def queued
45
+ gauges = []
46
+
47
+ @aggregated.each do |k,v|
48
+ gauges << {
49
+ :name => k.to_s,
50
+ :count => v.count,
51
+ :sum => v.sum,
52
+
53
+ # TODO: make float/non-float consistent in the gem
54
+ :min => v.min.to_f,
55
+ :max => v.max.to_f
56
+ # TODO: expose v.sum2 and include
57
+ }
58
+ end
59
+
60
+ req = { :gauges => gauges }
61
+ req[:source] = @source if @source
62
+
63
+ req
64
+ end
65
+
66
+ end
67
+ end
68
+ end
@@ -103,7 +103,7 @@ module Librato
103
103
  # expects 200
104
104
  url = connection.build_url("metrics/#{metric}", query)
105
105
  response = connection.get(url)
106
- parsed = MultiJson.decode(response.body)
106
+ parsed = MultiJson.load(response.body)
107
107
  # TODO: pagination support
108
108
  query.empty? ? parsed : parsed["measurements"]
109
109
  end
@@ -14,7 +14,7 @@ module Librato
14
14
  # expects 200
15
15
  url = connection.build_url(path, query)
16
16
  response = connection.get(url)
17
- parsed = MultiJson.decode(response.body)
17
+ parsed = MultiJson.load(response.body)
18
18
  results = parsed["metrics"]
19
19
  return results if parsed["query"]["found"] <= MAX_RESULTS
20
20
  query[:offset] = MAX_RESULTS
@@ -22,7 +22,7 @@ module Librato
22
22
  # expects 200
23
23
  url = connection.build_url(path, query)
24
24
  response = connection.get(url)
25
- parsed = MultiJson.decode(response.body)
25
+ parsed = MultiJson.load(response.body)
26
26
  results.push(*parsed["metrics"])
27
27
  query[:offset] += MAX_RESULTS
28
28
  end while query[:offset] < parsed["query"]["found"]
@@ -17,7 +17,7 @@ module Librato
17
17
  requests = [queued]
18
18
  end
19
19
  requests.each do |request|
20
- payload = MultiJson.encode(request)
20
+ payload = MultiJson.dump(request)
21
21
  # expects 200
22
22
  client.connection.post('metrics', payload)
23
23
  end
@@ -0,0 +1,78 @@
1
+ module Librato
2
+ module Metrics
3
+
4
+ module Processor
5
+ MEASUREMENTS_PER_REQUEST = 500
6
+
7
+ attr_reader :per_request
8
+
9
+ # The current Client instance this queue is using to authenticate
10
+ # and connect to Librato Metrics. This will default to the primary
11
+ # client used by the Librato::Metrics module unless it has been
12
+ # set to something else.
13
+ #
14
+ # @return [Librato::Metrics::Client]
15
+ def client
16
+ @client ||= Librato::Metrics.client
17
+ end
18
+
19
+ # The object this MetricSet will use to persist
20
+ #
21
+ def persister
22
+ @persister ||= create_persister
23
+ end
24
+
25
+ # Persist currently queued metrics
26
+ #
27
+ # @return Boolean
28
+ def submit
29
+ raise NoMetricsQueued if self.queued.empty?
30
+ options = {:per_request => @per_request}
31
+ if persister.persist(self.client, self.queued, options)
32
+ flush and return true
33
+ end
34
+ false
35
+ end
36
+
37
+ # Capture execution time for a block and queue
38
+ # it as the value for a metric. Times are recorded
39
+ # in milliseconds.
40
+ #
41
+ # Options are the same as for {#add}.
42
+ #
43
+ # @example Queue API request response time
44
+ # queue.time :api_request_time do
45
+ # # API request..
46
+ # end
47
+ #
48
+ # @example Queue API request response time w/ source
49
+ # queue.time :api_request_time, :source => 'app1' do
50
+ # # API request..
51
+ # end
52
+ #
53
+ # @param [Symbol|String] name Metric name
54
+ # @param [Hash] options Metric options
55
+ def time(name, options={})
56
+ start = Time.now
57
+ yield
58
+ duration = (Time.now - start) * 1000.0 # milliseconds
59
+ metric = {name => options.merge({:value => duration})}
60
+ add metric
61
+ end
62
+ alias :benchmark :time
63
+
64
+ private
65
+
66
+ def create_persister
67
+ type = self.client.persistence.to_s.capitalize
68
+ Librato::Metrics::Persistence.const_get(type).new
69
+ end
70
+
71
+ def epoch_time
72
+ Time.now.to_i
73
+ end
74
+
75
+ end
76
+
77
+ end
78
+ end
@@ -1,16 +1,18 @@
1
+ require 'metrics/processor'
2
+
3
+
1
4
  module Librato
2
5
  module Metrics
3
6
  class Queue
4
- MEASUREMENTS_PER_REQUEST = 500
7
+ include Processor
5
8
 
6
- attr_reader :per_request
7
9
  attr_accessor :skip_measurement_times
8
10
 
9
11
  def initialize(options={})
10
12
  @queued = {}
13
+ @client = options[:client] || Librato::Metrics.client
11
14
  @per_request = options[:per_request] || MEASUREMENTS_PER_REQUEST
12
15
  @skip_measurement_times = options[:skip_measurement_times]
13
- @client = options[:client] || Librato::Metrics.client
14
16
  end
15
17
 
16
18
  # Add a metric entry to the metric set:
@@ -37,16 +39,6 @@ module Librato
37
39
  queued
38
40
  end
39
41
 
40
- # The current Client instance this queue is using to authenticate
41
- # and connect to Librato Metrics. This will default to the primary
42
- # client used by the Librato::Metrics module unless it has been
43
- # set to something else.
44
- #
45
- # @return [Librato::Metrics::Client]
46
- def client
47
- @client ||= Librato::Metrics.client
48
- end
49
-
50
42
  # Currently queued counters
51
43
  #
52
44
  # @return [Array]
@@ -69,12 +61,6 @@ module Librato
69
61
  alias :clear :flush
70
62
  alias :flush_queued :flush
71
63
 
72
- # The object this MetricSet will use to persist
73
- #
74
- def persister
75
- @persister ||= create_persister
76
- end
77
-
78
64
  # Currently queued gauges
79
65
  #
80
66
  # @return Array
@@ -97,56 +83,6 @@ module Librato
97
83
  end
98
84
  alias :length :size
99
85
 
100
- # Persist currently queued metrics
101
- #
102
- # @return Boolean
103
- def submit
104
- raise NoMetricsQueued if self.queued.empty?
105
- options = {:per_request => @per_request}
106
- if persister.persist(self.client, self.queued, options)
107
- flush and return true
108
- end
109
- false
110
- end
111
-
112
- # Capture execution time for a block and queue
113
- # it as the value for a metric. Times are recorded
114
- # in milliseconds.
115
- #
116
- # Options are the same as for {#add}.
117
- #
118
- # @example Queue API request response time
119
- # queue.time :api_request_time do
120
- # # API request..
121
- # end
122
- #
123
- # @example Queue API request response time w/ source
124
- # queue.time :api_request_time, :source => 'app1' do
125
- # # API request..
126
- # end
127
- #
128
- # @param [Symbol|String] name Metric name
129
- # @param [Hash] options Metric options
130
- def time(name, options={})
131
- start = Time.now
132
- yield
133
- duration = (Time.now - start) * 1000.0 # milliseconds
134
- metric = {name => options.merge({:value => duration})}
135
- add metric
136
- end
137
- alias :benchmark :time
138
-
139
- private
140
-
141
- def create_persister
142
- type = self.client.persistence.to_s.capitalize
143
- Librato::Metrics::Persistence.const_get(type).new
144
- end
145
-
146
- def epoch_time
147
- Time.now.to_i
148
- end
149
-
150
86
  end
151
87
  end
152
88
  end
@@ -1,5 +1,5 @@
1
1
  module Librato
2
2
  module Metrics
3
- VERSION = "0.6.0.pre2"
3
+ VERSION = "0.6.0.pre3"
4
4
  end
5
5
  end
@@ -25,7 +25,8 @@ Gem::Specification.new do |s|
25
25
 
26
26
  ## runtime dependencies
27
27
  s.add_dependency 'faraday', '~>0.7.6'
28
- s.add_dependency 'multi_json'
28
+ s.add_dependency 'multi_json', '~>1.3.1'
29
+ s.add_dependency 'aggregate', '~>0.2.2'
29
30
 
30
31
  ## development dependencies
31
32
  s.add_development_dependency 'rake'
@@ -0,0 +1,173 @@
1
+ require "spec_helper.rb"
2
+ module Librato
3
+ module Metrics
4
+
5
+ describe Aggregator do
6
+
7
+ before(:all) do
8
+ @time = Time.now.to_i
9
+ Aggregator.stub(:epoch_time).and_return(@time)
10
+ end
11
+
12
+ describe "initialization" do
13
+ context "with specified client" do
14
+ it "should set to client" do
15
+ barney = Client.new
16
+ a = Aggregator.new(:client => barney)
17
+ a.client.should be barney
18
+ end
19
+ end
20
+
21
+ context "without specified client" do
22
+ it "should use Librato::Metrics client" do
23
+ a = Aggregator.new
24
+ a.client.should be Librato::Metrics.client
25
+ end
26
+ end
27
+
28
+ context "with specified source" do
29
+ it "should set to source" do
30
+ a = Aggregator.new(:source => 'rubble')
31
+ a.source.should == 'rubble'
32
+ end
33
+ end
34
+
35
+ context "without specified source" do
36
+ it "should not have a source" do
37
+ a = Aggregator.new
38
+ a.source.should be_nil
39
+ end
40
+ end
41
+ end
42
+
43
+ describe "#add" do
44
+ context "with single hash argument" do
45
+ it "should record a single aggregate" do
46
+ subject.add :foo => 3000
47
+ expected = { #:measure_time => @time, TODO: support specific time
48
+ :gauges => [
49
+ { :name => 'foo',
50
+ :count => 1,
51
+ :sum => 3000.0,
52
+ :min => 3000.0,
53
+ :max => 3000.0}
54
+ ]
55
+ }
56
+ subject.queued.should equal_unordered(expected)
57
+ end
58
+
59
+ it "should aggregate multiple measurements" do
60
+ subject.add :foo => 1
61
+ subject.add :foo => 2
62
+ subject.add :foo => 3
63
+ subject.add :foo => 4
64
+ subject.add :foo => 5
65
+ expected = { :gauges => [
66
+ { :name => 'foo',
67
+ :count => 5,
68
+ :sum => 15.0,
69
+ :min => 1.0,
70
+ :max => 5.0}
71
+ ]
72
+ }
73
+ subject.queued.should equal_unordered(expected)
74
+ end
75
+ end
76
+
77
+ context "with multiple hash arguments" do
78
+ it "should record a single aggregate" do
79
+ subject.add :foo => 3000
80
+ subject.add :bar => 30
81
+ expected = {
82
+ #:measure_time => @time, TODO: support specific time
83
+ :gauges => [
84
+ { :name => 'foo',
85
+ :count => 1,
86
+ :sum => 3000.0,
87
+ :min => 3000.0,
88
+ :max => 3000.0},
89
+ { :name => 'bar',
90
+ :count => 1,
91
+ :sum => 30.0,
92
+ :min => 30.0,
93
+ :max => 30.0},
94
+ ]
95
+ }
96
+ subject.queued.should equal_unordered(expected)
97
+ end
98
+
99
+ it "should aggregate multiple measurements" do
100
+ subject.add :foo => 1
101
+ subject.add :foo => 2
102
+ subject.add :foo => 3
103
+ subject.add :foo => 4
104
+ subject.add :foo => 5
105
+
106
+ subject.add :bar => 6
107
+ subject.add :bar => 7
108
+ subject.add :bar => 8
109
+ subject.add :bar => 9
110
+ subject.add :bar => 10
111
+ expected = { :gauges => [
112
+ { :name => 'foo',
113
+ :count => 5,
114
+ :sum => 15.0,
115
+ :min => 1.0,
116
+ :max => 5.0},
117
+ { :name => 'bar',
118
+ :count => 5,
119
+ :sum => 40.0,
120
+ :min => 6.0,
121
+ :max => 10.0}
122
+ ]
123
+ }
124
+ subject.queued.should equal_unordered(expected)
125
+ end
126
+ end
127
+ end
128
+
129
+ describe "#submit" do
130
+ before(:all) do
131
+ Librato::Metrics.authenticate 'me@librato.com', 'foo'
132
+ Librato::Metrics.persistence = :test
133
+ end
134
+
135
+ context "when successful" do
136
+ it "should flush queued metrics and return true" do
137
+ subject.add :steps => 2042, :distance => 1234
138
+ subject.submit.should be_true
139
+ subject.empty?.should be_true
140
+ end
141
+ end
142
+
143
+ context "when failed" do
144
+ it "should preserve queue and return false" do
145
+ subject.add :steps => 2042, :distance => 1234
146
+ subject.persister.return_value(false)
147
+ subject.submit.should be_false
148
+ subject.empty?.should be_false
149
+ end
150
+ end
151
+ end
152
+
153
+ describe "#time" do
154
+ context "with metric name only" do
155
+ it "should queue metric with timed value" do
156
+ 1.upto(5) do
157
+ subject.time :sleeping do
158
+ sleep 0.1
159
+ end
160
+ end
161
+ queued = subject.queued[:gauges][0]
162
+ queued[:name].should == 'sleeping'
163
+ queued[:count].should be 5
164
+ queued[:sum].should be > 500
165
+ queued[:sum].should be_within(150).of(500)
166
+ end
167
+ end
168
+ end
169
+
170
+ end
171
+
172
+ end
173
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: librato-metrics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0.pre2
4
+ version: 0.6.0.pre3
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-09 00:00:00.000000000Z
12
+ date: 2012-04-26 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
16
- requirement: &70288570431740 !ruby/object:Gem::Requirement
16
+ requirement: &70105435038240 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,21 +21,32 @@ dependencies:
21
21
  version: 0.7.6
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70288570431740
24
+ version_requirements: *70105435038240
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: multi_json
27
- requirement: &70288570431320 !ruby/object:Gem::Requirement
27
+ requirement: &70105435037740 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
- - - ! '>='
30
+ - - ~>
31
31
  - !ruby/object:Gem::Version
32
- version: '0'
32
+ version: 1.3.1
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70105435037740
36
+ - !ruby/object:Gem::Dependency
37
+ name: aggregate
38
+ requirement: &70105435037280 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 0.2.2
33
44
  type: :runtime
34
45
  prerelease: false
35
- version_requirements: *70288570431320
46
+ version_requirements: *70105435037280
36
47
  - !ruby/object:Gem::Dependency
37
48
  name: rake
38
- requirement: &70288570430860 !ruby/object:Gem::Requirement
49
+ requirement: &70105435036900 !ruby/object:Gem::Requirement
39
50
  none: false
40
51
  requirements:
41
52
  - - ! '>='
@@ -43,10 +54,10 @@ dependencies:
43
54
  version: '0'
44
55
  type: :development
45
56
  prerelease: false
46
- version_requirements: *70288570430860
57
+ version_requirements: *70105435036900
47
58
  - !ruby/object:Gem::Dependency
48
59
  name: rspec
49
- requirement: &70288570430360 !ruby/object:Gem::Requirement
60
+ requirement: &70105435068860 !ruby/object:Gem::Requirement
50
61
  none: false
51
62
  requirements:
52
63
  - - ~>
@@ -54,10 +65,10 @@ dependencies:
54
65
  version: 2.6.0
55
66
  type: :development
56
67
  prerelease: false
57
- version_requirements: *70288570430360
68
+ version_requirements: *70105435068860
58
69
  - !ruby/object:Gem::Dependency
59
70
  name: pry
60
- requirement: &70288570429940 !ruby/object:Gem::Requirement
71
+ requirement: &70105435068440 !ruby/object:Gem::Requirement
61
72
  none: false
62
73
  requirements:
63
74
  - - ! '>='
@@ -65,10 +76,10 @@ dependencies:
65
76
  version: '0'
66
77
  type: :development
67
78
  prerelease: false
68
- version_requirements: *70288570429940
79
+ version_requirements: *70105435068440
69
80
  - !ruby/object:Gem::Dependency
70
81
  name: yard
71
- requirement: &70288570429480 !ruby/object:Gem::Requirement
82
+ requirement: &70105435067980 !ruby/object:Gem::Requirement
72
83
  none: false
73
84
  requirements:
74
85
  - - ! '>='
@@ -76,10 +87,10 @@ dependencies:
76
87
  version: '0'
77
88
  type: :development
78
89
  prerelease: false
79
- version_requirements: *70288570429480
90
+ version_requirements: *70105435067980
80
91
  - !ruby/object:Gem::Dependency
81
92
  name: rdiscount
82
- requirement: &70288570429060 !ruby/object:Gem::Requirement
93
+ requirement: &70105435067560 !ruby/object:Gem::Requirement
83
94
  none: false
84
95
  requirements:
85
96
  - - ! '>='
@@ -87,10 +98,10 @@ dependencies:
87
98
  version: '0'
88
99
  type: :development
89
100
  prerelease: false
90
- version_requirements: *70288570429060
101
+ version_requirements: *70105435067560
91
102
  - !ruby/object:Gem::Dependency
92
103
  name: sinatra
93
- requirement: &70288570428640 !ruby/object:Gem::Requirement
104
+ requirement: &70105435067140 !ruby/object:Gem::Requirement
94
105
  none: false
95
106
  requirements:
96
107
  - - ! '>='
@@ -98,10 +109,10 @@ dependencies:
98
109
  version: '0'
99
110
  type: :development
100
111
  prerelease: false
101
- version_requirements: *70288570428640
112
+ version_requirements: *70105435067140
102
113
  - !ruby/object:Gem::Dependency
103
114
  name: popen4
104
- requirement: &70288570428220 !ruby/object:Gem::Requirement
115
+ requirement: &70105435066720 !ruby/object:Gem::Requirement
105
116
  none: false
106
117
  requirements:
107
118
  - - ! '>='
@@ -109,7 +120,7 @@ dependencies:
109
120
  version: '0'
110
121
  type: :development
111
122
  prerelease: false
112
- version_requirements: *70288570428220
123
+ version_requirements: *70105435066720
113
124
  description: An easy to use ruby wrapper for Librato's Metrics API
114
125
  email: matt@librato.com
115
126
  executables: []
@@ -126,6 +137,7 @@ files:
126
137
  - Rakefile
127
138
  - benchmarks/array_vs_set.rb
128
139
  - lib/librato/metrics.rb
140
+ - lib/librato/metrics/aggregator.rb
129
141
  - lib/librato/metrics/client.rb
130
142
  - lib/librato/metrics/collection.rb
131
143
  - lib/librato/metrics/connection.rb
@@ -137,6 +149,7 @@ files:
137
149
  - lib/librato/metrics/persistence.rb
138
150
  - lib/librato/metrics/persistence/direct.rb
139
151
  - lib/librato/metrics/persistence/test.rb
152
+ - lib/librato/metrics/processor.rb
140
153
  - lib/librato/metrics/queue.rb
141
154
  - lib/librato/metrics/version.rb
142
155
  - librato-metrics.gemspec
@@ -146,6 +159,7 @@ files:
146
159
  - spec/integration/metrics_spec.rb
147
160
  - spec/rackups/status.ru
148
161
  - spec/spec_helper.rb
162
+ - spec/unit/metrics/aggregator_spec.rb
149
163
  - spec/unit/metrics/client_spec.rb
150
164
  - spec/unit/metrics/connection_spec.rb
151
165
  - spec/unit/metrics/queue_spec.rb
@@ -182,6 +196,7 @@ test_files:
182
196
  - spec/integration/metrics_spec.rb
183
197
  - spec/rackups/status.ru
184
198
  - spec/spec_helper.rb
199
+ - spec/unit/metrics/aggregator_spec.rb
185
200
  - spec/unit/metrics/client_spec.rb
186
201
  - spec/unit/metrics/connection_spec.rb
187
202
  - spec/unit/metrics/queue_spec.rb