librato-metrics 0.5.0.pre1 → 0.5.0

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/.travis.yml CHANGED
@@ -1,5 +1,4 @@
1
1
  rvm:
2
- - 1.8.6
3
2
  - 1.8.7
4
3
  - ree
5
4
  - 1.9.2
data/CHANGELOG.md CHANGED
@@ -3,6 +3,7 @@
3
3
  ### Version 0.5.0
4
4
  * Support using multiple accounts simultaneously via Client
5
5
  * Switch network library to faraday for broader platform support and flexibility
6
+ * Automatically break large submissions into multiple requests for better performance
6
7
  * Automatic retry support
7
8
  * Consolidate connection functions in Connection
8
9
  * Documentation improvements
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  Librato Metrics
2
2
  =======
3
3
 
4
+ [![Build Status](https://secure.travis-ci.org/librato/librato-metrics.png?branch=master)](http://travis-ci.org/librato/librato-metrics)
5
+
4
6
  A convenient Ruby wrapper for the Librato Metrics API.
5
7
 
6
8
  ## Installation
@@ -140,19 +142,21 @@ Once the queue is associated you can use it normally:
140
142
 
141
143
  The `librato-metrics` gem currently does not do internal locking for thread safety. When used in multi-threaded applications, please add your own mutexes for sensitive operations.
142
144
 
143
- ## Known Issues & Coming Improvements
145
+ ## Feature Roadmap
144
146
 
145
- This is an early release and as such is lacking some capabilities slated for future releases.
147
+ These are features we expect to add in future versions, roughly in the order of current priority. If you feel strongly about a feature, feel free to [create an issue](https://github.com/librato/librato-metrics/issues) or [join us in live chat](https://librato.campfirenow.com/269d3) and talk to us about it.
146
148
 
147
- * Query actions currently do not auto-paginate with large result sets
148
- * Very large metric POSTs are not automatically chunked for performance
149
- * Some error conditions currently lack gem-specific exceptions
149
+ * Queue objects support a single default measure_time to use for any measurements which don't have it set
150
+ * Queues auto-submit when they hit a set number of records
151
+ * Queues auto-submit when they hit a max time interval
152
+ * Query actions return a collection object which auto-paginates large result sets
150
153
 
151
154
  ## Contribution
152
155
 
153
156
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
154
157
  * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
155
158
  * Fork the project and submit a pull request from a feature or bugfix branch.
159
+ * Please review our [code conventions](https://github.com/librato/librato-metrics/wiki/Code-Conventions).
156
160
  * Please include specs. This is important so we don't break your changes unintentionally in a future version.
157
161
  * Please don't modify the gemspec, Rakefile, version, or changelog. If you do change these files, please isolate a separate commit so we can cherry-pick around it.
158
162
 
@@ -1,4 +1,5 @@
1
1
  require 'faraday'
2
+ require 'metrics/middleware/count_requests'
2
3
  require 'metrics/middleware/expects_status'
3
4
  require 'metrics/middleware/retry'
4
5
 
@@ -29,6 +30,7 @@ module Librato
29
30
  @transport ||= Faraday::Connection.new(:url => api_endpoint + "/v1/") do |f|
30
31
  #f.use FaradayMiddleware::EncodeJson
31
32
  f.use Librato::Metrics::Middleware::Retry
33
+ f.use Librato::Metrics::Middleware::CountRequests
32
34
  f.use Librato::Metrics::Middleware::ExpectsStatus
33
35
  #f.use FaradayMiddleware::ParseJson, :content_type => /\bjson$/
34
36
  f.adapter Faraday.default_adapter
@@ -8,6 +8,16 @@ module Librato
8
8
  class AgentInfoMissing < MetricsError; end
9
9
  class NoMetricsQueued < MetricsError; end
10
10
  class NoClientProvided < MetricsError; end
11
+
12
+ class NetworkError < StandardError; end
13
+
14
+ class ClientError < NetworkError; end
15
+ class Unauthorized < ClientError; end
16
+ class Forbidden < ClientError; end
17
+ class NotFound < ClientError; end
18
+ class EntityAlreadyExists < ClientError; end
19
+
20
+ class ServerError < NetworkError; end
11
21
 
12
22
  end
13
23
  end
@@ -0,0 +1,29 @@
1
+ module Librato
2
+ module Metrics
3
+ module Middleware
4
+
5
+ class CountRequests < Faraday::Response::Middleware
6
+ @total_requests = 0
7
+
8
+ class << self
9
+ attr_reader :total_requests
10
+
11
+ def increment
12
+ @total_requests += 1
13
+ end
14
+
15
+ def reset
16
+ @total_requests = 0
17
+ end
18
+ end
19
+
20
+ def call(env)
21
+ self.class.increment
22
+ @app.call(env)
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+
@@ -8,10 +8,18 @@ module Librato
8
8
  # TODO: clean up exception output
9
9
  # TODO: catch specific status codes by request
10
10
  case env[:status]
11
+ when 401
12
+ raise Unauthorized, env.to_s
13
+ when 403
14
+ raise Forbidden, env.to_s
11
15
  when 404
12
- raise Faraday::Error::ResourceNotFound, env.to_s
13
- when 400..600
14
- raise Faraday::Error::ClientError, env.to_s
16
+ raise NotFound, env.to_s
17
+ when 422
18
+ raise EntityAlreadyExists, env.to_s
19
+ when 400..499
20
+ raise ClientError, env.to_s
21
+ when 500..599
22
+ raise ServerError, env.to_s
15
23
  end
16
24
  end
17
25
 
@@ -12,13 +12,14 @@ module Librato
12
12
 
13
13
  def call(env)
14
14
  retries = @retries
15
- @app.call(env)
16
- rescue StandardError, Timeout::Error
17
- if retries > 0
18
- retries -= 1
19
- retry
15
+ begin
16
+ @app.call(env)
17
+ rescue Librato::Metrics::ServerError, Timeout::Error
18
+ if retries > 0
19
+ retries -= 1 and retry
20
+ end
21
+ raise
20
22
  end
21
- raise
22
23
  end
23
24
 
24
25
  end
@@ -9,10 +9,42 @@ module Librato
9
9
  # Persist the queued metrics directly to the
10
10
  # Metrics web API.
11
11
  #
12
- def persist(client, queued)
13
- payload = MultiJson.encode(queued)
14
- # expects 200
15
- client.connection.post('metrics', payload)
12
+ def persist(client, queued, options={})
13
+ per_request = options[:per_request]
14
+ if per_request
15
+ requests = chunk_queued(queued, per_request)
16
+ else
17
+ requests = [queued]
18
+ end
19
+ requests.each do |request|
20
+ payload = MultiJson.encode(request)
21
+ # expects 200
22
+ client.connection.post('metrics', payload)
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def chunk_queued(queued, per_request)
29
+ return [queued] if queue_count(queued) <= per_request
30
+ reqs = []
31
+ queued.each do |metric_type, measurements|
32
+ if measurements.size <= per_request
33
+ # we can fit all of this metric type in a single
34
+ # request, so do so
35
+ reqs << {metric_type => measurements}
36
+ else
37
+ # going to have to split things up
38
+ measurements.each_slice(per_request) do |elements|
39
+ reqs << {metric_type => elements}
40
+ end
41
+ end
42
+ end
43
+ reqs
44
+ end
45
+
46
+ def queue_count(queued)
47
+ queued.inject(0) { |result, data| result + data.last.size }
16
48
  end
17
49
 
18
50
  end
@@ -6,7 +6,7 @@ module Librato
6
6
  class Test
7
7
 
8
8
  # persist the given metrics
9
- def persist(client, metrics)
9
+ def persist(client, metrics, options={})
10
10
  @persisted = metrics
11
11
  return !@return_value.nil? ? @return_value : true
12
12
  end
@@ -1,13 +1,16 @@
1
1
  module Librato
2
2
  module Metrics
3
3
  class Queue
4
+ MEASUREMENTS_PER_REQUEST = 500
4
5
 
6
+ attr_reader :per_request
5
7
  attr_accessor :skip_measurement_times
6
8
 
7
9
  def initialize(options={})
8
- @queued ||= {}
9
- @skip_measurement_times = options.delete(:skip_measurement_times)
10
- @client = options.delete(:client) || Librato::Metrics.client
10
+ @queued = {}
11
+ @per_request = options[:per_request] || MEASUREMENTS_PER_REQUEST
12
+ @skip_measurement_times = options[:skip_measurement_times]
13
+ @client = options[:client] || Librato::Metrics.client
11
14
  end
12
15
 
13
16
  # Add a metric entry to the metric set:
@@ -99,7 +102,8 @@ module Librato
99
102
  # @return Boolean
100
103
  def submit
101
104
  raise NoMetricsQueued if self.queued.empty?
102
- if persister.persist(self.client, self.queued)
105
+ options = {:per_request => @per_request}
106
+ if persister.persist(self.client, self.queued, options)
103
107
  flush and return true
104
108
  end
105
109
  false
@@ -1,5 +1,5 @@
1
1
  module Librato
2
2
  module Metrics
3
- VERSION = "0.5.0.pre1"
3
+ VERSION = "0.5.0"
4
4
  end
5
5
  end
@@ -33,6 +33,8 @@ Gem::Specification.new do |s|
33
33
  s.add_development_dependency 'pry'
34
34
  s.add_development_dependency 'yard'
35
35
  s.add_development_dependency 'rdiscount' # for yard
36
+ s.add_development_dependency 'sinatra'
37
+ s.add_development_dependency 'popen4'
36
38
 
37
39
  s.files = `git ls-files`.split("\n")
38
40
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ module Librato
4
+ module Metrics
5
+ module Middleware
6
+
7
+ describe CountRequests do
8
+ before(:all) { prep_integration_tests }
9
+
10
+ it "should count requests" do
11
+ CountRequests.reset
12
+ Metrics.submit :foo => 123
13
+ Metrics.submit :foo => 135
14
+ CountRequests.total_requests.should == 2
15
+ end
16
+
17
+ it "should be resettable" do
18
+ Metrics.submit :foo => 123
19
+ CountRequests.total_requests.should > 0
20
+ CountRequests.reset
21
+ CountRequests.total_requests.should == 0
22
+ end
23
+
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ module Librato
4
+ module Metrics
5
+
6
+ describe Queue do
7
+ before(:all) { prep_integration_tests }
8
+
9
+ context "with a large number of metrics" do
10
+ it "should submit them in multiple requests" do
11
+ Middleware::CountRequests.reset
12
+ queue = Queue.new(:per_request => 3)
13
+ (1..10).each do |i|
14
+ queue.add "gauge_#{i}" => 1
15
+ end
16
+ queue.submit
17
+ Middleware::CountRequests.total_requests.should == 4
18
+ end
19
+
20
+ it "should persist all metrics" do
21
+ queue = Queue.new(:per_request => 2)
22
+ (1..5).each do |i|
23
+ queue.add "gauge_#{i}" => i
24
+ end
25
+ (1..3).each do |i|
26
+ queue.add "counter_#{i}" => {:type => :counter, :value => i}
27
+ end
28
+
29
+ delete_all_metrics
30
+ queue.submit
31
+
32
+ metrics = Metrics.list
33
+ metrics.length.should == 8
34
+ counter = Metrics.fetch :counter_3, :count => 1
35
+ counter['unassigned'][0]['value'].should == 3
36
+ gauge = Metrics.fetch :gauge_5, :count => 1
37
+ gauge['unassigned'][0]['value'].should == 5
38
+ end
39
+ end
40
+ end
41
+
42
+ end
43
+ end
@@ -7,11 +7,12 @@ module Librato
7
7
  describe "#fetch" do
8
8
  before(:all) do
9
9
  delete_all_metrics
10
- Metrics.submit :my_counter => {:type => :counter, :value => 0}
10
+ Metrics.submit :my_counter => {:type => :counter, :value => 0, :measure_time => Time.now.to_i-60}
11
11
  1.upto(2).each do |i|
12
- sleep 1
13
- Metrics.submit :my_counter => {:type => :counter, :value => i}
14
- Metrics.submit :my_counter => {:source => 'baz', :type => :counter, :value => i+1}
12
+ measure_time = Time.now.to_i - (5+i)
13
+ opts = {:measure_time => measure_time, :type => :counter}
14
+ Metrics.submit :my_counter => opts.merge(:value => i)
15
+ Metrics.submit :my_counter => opts.merge(:source => 'baz', :value => i+1)
15
16
  end
16
17
  end
17
18
 
@@ -0,0 +1,21 @@
1
+ require 'sinatra'
2
+
3
+ class App < Sinatra::Base
4
+ get('/v1/success') do
5
+ status 200
6
+ end
7
+
8
+ post('/v1/forbidden') do
9
+ status 403
10
+ end
11
+
12
+ get('/v1/not_found') do
13
+ status 404
14
+ end
15
+
16
+ post('/v1/service_unavailable') do
17
+ status 503
18
+ end
19
+ end
20
+
21
+ run App
data/spec/spec_helper.rb CHANGED
@@ -1,13 +1,26 @@
1
1
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
 
3
- require 'pry'
3
+ # only load pry for MRI > 1.8
4
+ require 'pry' if RUBY_ENGINE == 'ruby' rescue nil
5
+ require 'popen4'
4
6
  require 'rspec'
5
7
  require 'rspec/mocks/standalone'
8
+ require 'set'
6
9
 
7
10
  require 'librato/metrics'
8
11
 
9
12
  RSpec.configure do |config|
10
-
13
+
14
+ # purge all metrics from test account
15
+ def delete_all_metrics
16
+ connection = Librato::Metrics.client.connection
17
+ Librato::Metrics.list.each do |metric|
18
+ #puts "deleting #{metric['name']}..."
19
+ # expects 204
20
+ connection.delete("metrics/#{metric['name']}")
21
+ end
22
+ end
23
+
11
24
  # set up test account credentials for integration tests
12
25
  def prep_integration_tests
13
26
  raise 'no TEST_API_USER specified in environment' unless ENV['TEST_API_USER']
@@ -17,14 +30,26 @@ RSpec.configure do |config|
17
30
  end
18
31
  Librato::Metrics.authenticate ENV['TEST_API_USER'], ENV['TEST_API_KEY']
19
32
  end
20
-
21
- # purge all metrics from test account
22
- def delete_all_metrics
23
- connection = Librato::Metrics.client.connection
24
- Librato::Metrics.list.each do |metric|
25
- #puts "deleting #{metric['name']}..."
26
- # expects 204
27
- connection.delete("metrics/#{metric['name']}")
33
+
34
+ def rackup_path(*parts)
35
+ File.expand_path(File.join(File.dirname(__FILE__), 'rackups', *parts))
36
+ end
37
+
38
+ # fire up a given rackup file for the enclosed tests
39
+ def with_rackup(name)
40
+ if RUBY_PLATFORM == 'java'
41
+ pid, w, r, e = IO.popen4("rackup", rackup_path(name), '-p 9296')
42
+ else
43
+ GC.disable
44
+ pid, w, r, e = Open4.popen4("rackup", rackup_path(name), '-p 9296')
45
+ end
46
+ until e.gets =~ /HTTPServer#start:/; end
47
+ yield
48
+ ensure
49
+ Process.kill(9, pid)
50
+ if RUBY_PLATFORM != 'java'
51
+ GC.enable
52
+ Process.wait(pid)
28
53
  end
29
54
  end
30
55
 
@@ -37,4 +62,17 @@ RSpec::Matchers.define :start_with do |start_string|
37
62
  start_length = start_string.length
38
63
  string[0..start_length-1] == start_string
39
64
  end
65
+ end
66
+
67
+ # Compares hashes of arrays by converting the arrays to
68
+ # sets before comparision
69
+ #
70
+ # @example
71
+ # {:foo => [1,3,2]}.should equal_unordered({:foo => [1,2,3]})
72
+ RSpec::Matchers.define :equal_unordered do |result|
73
+ result.each { |key, value| result[key] = value.to_set }
74
+ match do |target|
75
+ target.each { |key, value| target[key] = value.to_set }
76
+ target == result
77
+ end
40
78
  end
@@ -92,7 +92,7 @@ module Librato
92
92
  subject.authenticate 'me@librato.com', 'foo'
93
93
  subject.persistence = :test
94
94
  subject.submit(:foo => 123).should eql true
95
- subject.persister.persisted.should eql({:gauges => [{:name => 'foo', :value => 123}]})
95
+ subject.persister.persisted.should == {:gauges => [{:name => 'foo', :value => 123}]}
96
96
  end
97
97
 
98
98
  it "should tolerate muliple metrics" do
@@ -100,7 +100,7 @@ module Librato
100
100
  subject.persistence = :test
101
101
  lambda{ subject.submit :foo => 123, :bar => 456 }.should_not raise_error
102
102
  expected = {:gauges => [{:name => 'foo', :value => 123}, {:name => 'bar', :value => 456}]}
103
- subject.persister.persisted.should eql expected
103
+ subject.persister.persisted.should equal_unordered(expected)
104
104
  end
105
105
  end
106
106
 
@@ -5,14 +5,6 @@ module Librato
5
5
 
6
6
  describe Connection do
7
7
 
8
- describe "network operations" do
9
- context "when missing client" do
10
- it "should raise exception" do
11
- lambda { subject.get 'metrics' }#.should raise(NoClientProvided)
12
- end
13
- end
14
- end
15
-
16
8
  describe "#api_endpoint" do
17
9
  context "when not provided" do
18
10
  it "should be default" do
@@ -48,6 +40,46 @@ module Librato
48
40
  # TODO: verify user agent is being sent with rackup test
49
41
  end
50
42
 
43
+ describe "network operations" do
44
+ context "when missing client" do
45
+ it "should raise exception" do
46
+ lambda { subject.get 'metrics' }.should raise_error(NoClientProvided)
47
+ end
48
+ end
49
+
50
+ context "with 400 class errors" do
51
+ it "should not retry" do
52
+ Middleware::CountRequests.reset
53
+ client = Client.new
54
+ client.api_endpoint = 'http://127.0.0.1:9296'
55
+ client.authenticate 'foo', 'bar'
56
+ with_rackup('status.ru') do
57
+ lambda {
58
+ client.connection.transport.post 'not_found'
59
+ }.should raise_error(NotFound)
60
+ lambda {
61
+ client.connection.transport.post 'forbidden'
62
+ }.should raise_error(ClientError)
63
+ end
64
+ Middleware::CountRequests.total_requests.should == 2
65
+ end
66
+ end
67
+
68
+ context "with 500 class errors" do
69
+ it "should retry" do
70
+ Middleware::CountRequests.reset
71
+ client = Client.new
72
+ client.api_endpoint = 'http://127.0.0.1:9296'
73
+ client.authenticate 'foo', 'bar'
74
+ with_rackup('status.ru') do
75
+ lambda {
76
+ client.connection.transport.post 'service_unavailable'
77
+ }.should raise_error(ServerError)
78
+ end
79
+ Middleware::CountRequests.total_requests.should == 4
80
+ end
81
+ end
82
+ end
51
83
 
52
84
  end
53
85
 
@@ -1,11 +1,11 @@
1
- require "spec_helper.rb"
1
+ require "spec_helper"
2
2
 
3
3
  module Librato
4
4
  module Metrics
5
5
 
6
6
  describe Queue do
7
7
 
8
- before(:all) do
8
+ before(:each) do
9
9
  @time = Time.now.to_i
10
10
  Queue.stub(:epoch_time).and_return(@time)
11
11
  end
@@ -30,8 +30,9 @@ module Librato
30
30
  describe "#add" do
31
31
  context "with single hash argument" do
32
32
  it "should record a key-value gauge" do
33
+ expected = {:gauges => [{:name => 'foo', :value => 3000, :measure_time => @time}]}
33
34
  subject.add :foo => 3000
34
- subject.queued.should eql({:gauges => [{:name => 'foo', :value => 3000, :measure_time => @time}]})
35
+ subject.queued.should equal_unordered(expected)
35
36
  end
36
37
  end
37
38
 
@@ -39,19 +40,19 @@ module Librato
39
40
  it "should record counters" do
40
41
  subject.add :total_visits => {:type => :counter, :value => 4000}
41
42
  expected = {:counters => [{:name => 'total_visits', :value => 4000, :measure_time => @time}]}
42
- subject.queued.should eql expected
43
+ subject.queued.should equal_unordered(expected)
43
44
  end
44
45
 
45
46
  it "should record gauges" do
46
47
  subject.add :temperature => {:type => :gauge, :value => 34}
47
48
  expected = {:gauges => [{:name => 'temperature', :value => 34, :measure_time => @time}]}
48
- subject.queued.should eql expected
49
+ subject.queued.should equal_unordered(expected)
49
50
  end
50
51
 
51
52
  it "should accept type key as string or a symbol" do
52
53
  subject.add :total_visits => {"type" => "counter", :value => 4000}
53
54
  expected = {:counters => [{:name => 'total_visits', :value => 4000, :measure_time => @time}]}
54
- subject.queued.should eql expected
55
+ subject.queued.should equal_unordered(expected)
55
56
  end
56
57
  end
57
58
 
@@ -64,7 +65,7 @@ module Librato
64
65
  expected = {:gauges => [{:value => 35.4, :name => 'disk_use', :period => 2,
65
66
  :description => 'current disk utilization', :measure_time => measure_time,
66
67
  :source => 'db2'}]}
67
- subject.queued.should eql expected
68
+ subject.queued.should equal_unordered(expected)
68
69
  end
69
70
  end
70
71
 
@@ -74,7 +75,7 @@ module Librato
74
75
  expected = {:gauges=>[{:name=>"foo", :value=>123, :measure_time => @time},
75
76
  {:name=>"bar", :value=>345, :measure_time => @time},
76
77
  {:name=>"baz", :value=>567, :measure_time => @time}]}
77
- subject.queued.should eql expected
78
+ subject.queued.should equal_unordered(expected)
78
79
  end
79
80
  end
80
81
  end
@@ -113,6 +114,12 @@ module Librato
113
114
  subject.gauges.should eql []
114
115
  end
115
116
  end
117
+
118
+ describe "#per_request" do
119
+ it "should default to 500" do
120
+ subject.per_request.should == 500
121
+ end
122
+ end
116
123
 
117
124
  describe "#size" do
118
125
  it "should return empty if gauges and counters are emtpy" do
@@ -159,7 +166,7 @@ module Librato
159
166
  end
160
167
  queued = subject.queued[:gauges][0]
161
168
  queued[:name].should == 'sleeping'
162
- queued[:value].should be > 100
169
+ queued[:value].should be >= 100
163
170
  queued[:value].should be_within(30).of(100)
164
171
  end
165
172
  end
@@ -173,7 +180,7 @@ module Librato
173
180
  queued[:name].should == 'sleep_two'
174
181
  queued[:period].should == 2
175
182
  queued[:source].should == 'app1'
176
- queued[:value].should be > 50
183
+ queued[:value].should be >= 50
177
184
  queued[:value].should be_within(30).of(50)
178
185
  end
179
186
  end
@@ -35,13 +35,13 @@ module Librato
35
35
  it "should persist metrics immediately" do
36
36
  Metrics.persistence = :test
37
37
  Metrics.submit(:foo => 123).should eql true
38
- Metrics.persister.persisted.should eql({:gauges => [{:name => 'foo', :value => 123}]})
38
+ Metrics.persister.persisted.should == {:gauges => [{:name => 'foo', :value => 123}]}
39
39
  end
40
40
 
41
41
  it "should tolerate multiple metrics" do
42
42
  lambda{ Librato::Metrics.submit :foo => 123, :bar => 456 }.should_not raise_error
43
43
  expected = {:gauges => [{:name => 'foo', :value => 123}, {:name => 'bar', :value => 456}]}
44
- Librato::Metrics.persister.persisted.should eql expected
44
+ Librato::Metrics.persister.persisted.should equal_unordered(expected)
45
45
  end
46
46
 
47
47
  end
metadata CHANGED
@@ -1,19 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: librato-metrics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0.pre1
5
- prerelease: 6
4
+ version: 0.5.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Matt Sanders
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-26 00:00:00.000000000Z
12
+ date: 2012-04-02 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
16
- requirement: &70341863470180 !ruby/object:Gem::Requirement
16
+ requirement: &70301317338000 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.7.6
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70341863470180
24
+ version_requirements: *70301317338000
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: multi_json
27
- requirement: &70341863469760 !ruby/object:Gem::Requirement
27
+ requirement: &70301317369580 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70341863469760
35
+ version_requirements: *70301317369580
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- requirement: &70341863469300 !ruby/object:Gem::Requirement
38
+ requirement: &70301317369120 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70341863469300
46
+ version_requirements: *70301317369120
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec
49
- requirement: &70341863468800 !ruby/object:Gem::Requirement
49
+ requirement: &70301317368620 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 2.6.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70341863468800
57
+ version_requirements: *70301317368620
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: pry
60
- requirement: &70341863468380 !ruby/object:Gem::Requirement
60
+ requirement: &70301317368200 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70341863468380
68
+ version_requirements: *70301317368200
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: yard
71
- requirement: &70341863467920 !ruby/object:Gem::Requirement
71
+ requirement: &70301317367740 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70341863467920
79
+ version_requirements: *70301317367740
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rdiscount
82
- requirement: &70341863467500 !ruby/object:Gem::Requirement
82
+ requirement: &70301317367320 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,7 +87,29 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70341863467500
90
+ version_requirements: *70301317367320
91
+ - !ruby/object:Gem::Dependency
92
+ name: sinatra
93
+ requirement: &70301317366900 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *70301317366900
102
+ - !ruby/object:Gem::Dependency
103
+ name: popen4
104
+ requirement: &70301317366480 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *70301317366480
91
113
  description: An easy to use ruby wrapper for Librato's Metrics API
92
114
  email: matt@librato.com
93
115
  executables: []
@@ -107,6 +129,7 @@ files:
107
129
  - lib/librato/metrics/collection.rb
108
130
  - lib/librato/metrics/connection.rb
109
131
  - lib/librato/metrics/errors.rb
132
+ - lib/librato/metrics/middleware/count_requests.rb
110
133
  - lib/librato/metrics/middleware/expects_status.rb
111
134
  - lib/librato/metrics/middleware/retry.rb
112
135
  - lib/librato/metrics/persistence.rb
@@ -116,7 +139,10 @@ files:
116
139
  - lib/librato/metrics/version.rb
117
140
  - librato-metrics.gemspec
118
141
  - spec/integration/metrics/connection_spec.rb
142
+ - spec/integration/metrics/middleware/count_requests_spec.rb
143
+ - spec/integration/metrics/queue_spec.rb
119
144
  - spec/integration/metrics_spec.rb
145
+ - spec/rackups/status.ru
120
146
  - spec/spec_helper.rb
121
147
  - spec/unit/metrics/client_spec.rb
122
148
  - spec/unit/metrics/connection_spec.rb
@@ -138,9 +164,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
138
164
  required_rubygems_version: !ruby/object:Gem::Requirement
139
165
  none: false
140
166
  requirements:
141
- - - ! '>'
167
+ - - ! '>='
142
168
  - !ruby/object:Gem::Version
143
- version: 1.3.1
169
+ version: '0'
144
170
  requirements: []
145
171
  rubyforge_project:
146
172
  rubygems_version: 1.8.16
@@ -149,7 +175,10 @@ specification_version: 2
149
175
  summary: Ruby wrapper for Librato's Metrics API
150
176
  test_files:
151
177
  - spec/integration/metrics/connection_spec.rb
178
+ - spec/integration/metrics/middleware/count_requests_spec.rb
179
+ - spec/integration/metrics/queue_spec.rb
152
180
  - spec/integration/metrics_spec.rb
181
+ - spec/rackups/status.ru
153
182
  - spec/spec_helper.rb
154
183
  - spec/unit/metrics/client_spec.rb
155
184
  - spec/unit/metrics/connection_spec.rb