librato-metrics 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ .rvmrc
2
+ .bundle
3
+ .DS_Store
4
+ Gemfile.lock
5
+ *.gem
6
+
7
+ # docs
8
+ rdoc
9
+ doc
10
+ .yardoc
11
+
12
+ # textmate
13
+ *.tmproj
14
+
15
+ # vim
16
+ *.swp
17
+
18
+ # rcov generated
19
+ coverage
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,11 @@
1
+ Librato Software Confidential and Proprietary
2
+
3
+ Copyright (C) 2011, Librato Inc. ALL RIGHTS RESERVED.
4
+
5
+ Except as specifically permitted herein, no portion of the
6
+ information, including but not limited to object code and source
7
+ code, may be reproduced, modified, distributed, republished or
8
+ otherwise utilized in any form or by any means for any purpose
9
+ without the prior written permission of Librato Inc.
10
+
11
+ Visit http://librato.com for more information.
data/README.md ADDED
@@ -0,0 +1,114 @@
1
+ Librato Metrics
2
+ =======
3
+
4
+ A convenient Ruby wrapper for the Librato Metrics API.
5
+
6
+ ## Installation
7
+
8
+ In your shell:
9
+
10
+ gem install librato-metrics
11
+
12
+ Then, in your application or script:
13
+
14
+ require 'librato/metrics'
15
+
16
+ ## Quick Start
17
+
18
+ If you are looking for the quickest possible route to getting a data into Metrics, you only need two lines:
19
+
20
+ Librato::Metrics.authenticate 'email', 'api_key'
21
+ Librato::Metrics.submit :my_metric => 42, :my_other_metric => 1002
22
+
23
+ Unspecified metrics will send a *gauge*, but if you need to send a different metric type or include additional properties, simply use a hash:
24
+
25
+ Librato::Metrics.submit :my_metric => {:type => :counter, :value => 1002, :source => 'myapp'}
26
+
27
+ While this is all you need to get started, if you are sending a number of metrics regularly a queue may be easier/more performant so read on...
28
+
29
+ ## Authentication
30
+
31
+ Make sure you have [an account for Metrics](https://metrics.librato.com/) and then authenticate with your email and API key (on your account page):
32
+
33
+ Librato::Metrics.authenticate 'email', 'api_key'
34
+
35
+ ## Sending Metrics
36
+
37
+ 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.
38
+
39
+ Queue up a simple gauge metric named `temperature`:
40
+
41
+ queue = Librato::Metrics::Queue.new
42
+ queue.add :temperature => 32.2
43
+
44
+ If you are tracking measurements over several seconds/minutes, the queue will handle storing measurement time for you (otherwise all metrics will be recorded as measured when they are submitted).
45
+
46
+ You can queue multiple metrics at once. Here's a gauge (`load`) and a counter (`visits`):
47
+
48
+ queue.add :load => 2.2, :visits => {:type => :counter, :value => 400}
49
+
50
+ Queue up a metric with a specified source:
51
+
52
+ queue.add :cpu => {:source => 'app1', :value => 92.6}
53
+
54
+ A complete [list of metric attributes](http://dev.librato.com/v1/metrics) is available in the [API documentation](http://dev.librato.com/v1).
55
+
56
+ Save all queued metrics:
57
+
58
+ queue.submit
59
+
60
+ ## Benchmarking
61
+
62
+ If you have operations in your application you want to record execution time for, you can use the `#time` method:
63
+
64
+ queue.time :my_measurement do
65
+ # do work...
66
+ end
67
+
68
+ If you need extra attributes for the measurement, simply add them on:
69
+
70
+ queue.time :my_measurement, :source => 'app1' do
71
+ # do work...
72
+ end
73
+
74
+ ## Querying Metrics
75
+
76
+ Get name and properties for all metrics you have in the system:
77
+
78
+ metrics = Librato::Metrics.list
79
+
80
+ Get only metrics whose name includes `time`:
81
+
82
+ metrics = Librato::Metrics.list :name => 'time'
83
+
84
+ ## Querying Metric Data
85
+
86
+ Get attributes for metric `temperature`:
87
+
88
+ data = Librato::Metrics.fetch :temperature
89
+
90
+ Get the 20 most recent data points for `temperature`:
91
+
92
+ data = Librato::Metrics.fetch :temperature, :count => 20
93
+
94
+ Get the 20 most recent data points for `temperature` from a specific source:
95
+
96
+ data = Librato::Metrics.fetch :temperature, :count => 20, :source => 'app1'
97
+
98
+ Get the 20 most recent 15 minute data point rollups for `temperature`:
99
+
100
+ data = Librato::Metrics.fetch :temperature, :count => 20, :resolution => 900
101
+
102
+ There are many more options supported for querying, take a look at the [REST API docs](http://dev.librato.com/v1/get/gauges/:name) for more details.
103
+
104
+ ## Contribution
105
+
106
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
107
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
108
+ * Fork the project and submit a pull request from a feature or bugfix branch.
109
+ * Please include specs. This is important so we don't break your changes unintentionally in a future version.
110
+ * Please don't modify the Rakefile, version, or history. If you do change these files, please isolate a separate commit so we can cherry-pick around it.
111
+
112
+ ## Copyright
113
+
114
+ Copyright (c) 2011-2012 [Librato Inc.](http://librato.com) See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ require 'bundler'
2
+
3
+ # Packaging
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ # Testing
7
+ require 'rspec/core/rake_task'
8
+ RSpec::Core::RakeTask.new(:spec) do |t|
9
+ t.rspec_opts = '--color'
10
+ end
11
+
12
+ task :default => :spec
13
+ task :test => :spec
14
+
15
+ # Docs
16
+ require 'yard'
17
+ YARD::Rake::YardocTask.new
18
+
19
+ # IRB
20
+ desc "Open an irb session preloaded with this library"
21
+ task :console do
22
+ sh "irb -rubygems -r ./lib/librato/metrics.rb"
23
+ end
24
+
@@ -0,0 +1,89 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'base64'
5
+ require 'excon'
6
+ require 'json'
7
+
8
+ require 'metrics/errors'
9
+ require 'metrics/persistence'
10
+ require 'metrics/queue'
11
+ require 'metrics/simple'
12
+ require 'metrics/version'
13
+
14
+ module Librato
15
+
16
+ # Metrics provides a simple wrapper for the Metrics web API. Some
17
+ # of the methods Metrics provides will be documented below. Others
18
+ # are delegated to {Librato::Metrics::Simple} and will be
19
+ # documented there.
20
+ module Metrics
21
+ extend SingleForwardable
22
+
23
+ TYPES = [:counter, :gauge]
24
+
25
+ # Expose class methods of Simple via Metrics itself.
26
+ #
27
+ # TODO: Explain exposed interface with examples.
28
+ def_delegators Librato::Metrics::Simple, :api_endpoint, :api_endpoint=,
29
+ :authenticate, :connection, :persistence, :persistence=,
30
+ :persister, :submit
31
+
32
+ # Query metric data
33
+ #
34
+ # @example Get attributes for a metric
35
+ # attrs = Librato::Metrics.fetch :temperature
36
+ #
37
+ # @example Get 20 most recent data points for metric
38
+ # data = Librato::Metrics.fetch :temperature, :count => 20
39
+ #
40
+ # @example Get 20 most recent data points for a specific source
41
+ # data = Librato::Metrics.fetch :temperature, :count => 20,
42
+ # :source => 'app1'
43
+ #
44
+ # @example Get the 20 most recent 15 minute data point rollups
45
+ # data = Librato::Metrics.fetch :temperature, :count => 20,
46
+ # :resolution => 900
47
+ #
48
+ # A full list of query parameters can be found in the API
49
+ # documentation: {http://dev.librato.com/v1/get/gauges/:name}
50
+ #
51
+ # @param [Symbol|String] metric Metric name
52
+ # @param [Hash] options Query options
53
+ def self.fetch(metric, options={})
54
+ resolution = options.delete(:resolution) || 1
55
+ count = options.delete(:count)
56
+ query = {}
57
+ if count
58
+ query.merge!({:count => count, :resolution => resolution})
59
+ end
60
+ query.merge!(options)
61
+ # TODO: look up type when not specified.
62
+ type = options.delete(:type) || 'gauge'
63
+ response = connection.get(:path => "v1/#{type}s/#{metric}.json",
64
+ :query => query, :expects => 200)
65
+ parsed = JSON.parse(response.body)
66
+ # TODO: pagination support
67
+ query.empty? ? parsed : parsed["measurements"]
68
+ end
69
+
70
+ # List currently existing metrics
71
+ #
72
+ # @example List all metrics
73
+ # Librato::Metrics.list
74
+ #
75
+ # @example List metrics with 'foo' in the name
76
+ # Librato::Metrics.list :name => 'foo'
77
+ #
78
+ # @param [Hash] options
79
+ def self.list(options={})
80
+ query = {}
81
+ query[:name] = options[:name] if options[:name]
82
+ response = connection.get(:path => 'v1/metrics.json',
83
+ :query => query, :expects => 200)
84
+ # TODO: pagination support
85
+ JSON.parse(response.body)["metrics"]
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,11 @@
1
+
2
+ module Librato
3
+ module Metrics
4
+
5
+ class MetricsError < StandardError; end
6
+
7
+ class CredentialsMissing < MetricsError; end
8
+ class NoMetricsQueued < MetricsError; end
9
+
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+
2
+ require 'metrics/persistence/direct'
3
+ require 'metrics/persistence/test'
@@ -0,0 +1,22 @@
1
+
2
+ # Manages direct persistence with the Librato Metrics web API
3
+
4
+ module Librato
5
+ module Metrics
6
+ module Persistence
7
+ class Direct
8
+
9
+ # Persist the queued metrics directly to the
10
+ # Metrics web API.
11
+ #
12
+ def persist(queued)
13
+ payload = queued.to_json
14
+ Simple.connection.post(:path => '/v1/metrics.json',
15
+ :headers => {'Content-Type' => 'application/json'},
16
+ :body => payload, :expects => 200)
17
+ end
18
+
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,27 @@
1
+ # Use for testing the interface with persistence methods
2
+
3
+ module Librato
4
+ module Metrics
5
+ module Persistence
6
+ class Test
7
+
8
+ # persist the given metrics
9
+ def persist(metrics)
10
+ @persisted = metrics
11
+ return !@return_value.nil? ? @return_value : true
12
+ end
13
+
14
+ # return what was persisted
15
+ def persisted
16
+ @persisted
17
+ end
18
+
19
+ # force a return value from persistence
20
+ def return_value(value)
21
+ @return_value = value
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,110 @@
1
+ module Librato
2
+ module Metrics
3
+ class Queue
4
+
5
+ def initialize
6
+ @queued ||= {}
7
+ end
8
+
9
+ # Add a metric entry to the metric set:
10
+ #
11
+ # @param Hash metrics metrics to add
12
+ # @return Hash queued_metrics the currently queued metrics
13
+ def add(args)
14
+ args.each do |key, value|
15
+ if value.respond_to?(:each)
16
+ type = (value.delete(:type) || 'gauge')
17
+ type = ("#{type}s").to_sym
18
+ value[:name] = key.to_s
19
+ @queued[type] ||= []
20
+ @queued[type] << value
21
+ else
22
+ @queued[:gauges] ||= []
23
+ @queued[:gauges] << {:name => key.to_s, :value => value}
24
+ end
25
+ end
26
+ queued
27
+ end
28
+
29
+ # Currently queued counters
30
+ #
31
+ # @return Array
32
+ def counters
33
+ @queued[:counters] || []
34
+ end
35
+
36
+ # Remove all queued metrics
37
+ #
38
+ def flush
39
+ @queued = {}
40
+ end
41
+ alias :flush_queued :flush
42
+
43
+ # The object this MetricSet will use to persist
44
+ #
45
+ def persister
46
+ @persister ||= create_persister
47
+ end
48
+
49
+ # Currently queued gauges
50
+ #
51
+ # @return Array
52
+ def gauges
53
+ @queued[:gauges] || []
54
+ end
55
+
56
+ # All currently queued metrics
57
+ #
58
+ # @return Hash
59
+ def queued
60
+ @queued
61
+ end
62
+
63
+ # Persist currently queued metrics
64
+ #
65
+ # @return Boolean
66
+ def submit
67
+ raise NoMetricsQueued if self.queued.empty?
68
+ if persister.persist(self.queued)
69
+ flush and return true
70
+ end
71
+ false
72
+ end
73
+
74
+ # Capture execution time for a block and queue
75
+ # it as the value for a metric. Times are recorded
76
+ # in milliseconds.
77
+ #
78
+ # Options are the same as for {#add}.
79
+ #
80
+ # @example Queue API request response time
81
+ # queue.time :api_request_time do
82
+ # # API request..
83
+ # end
84
+ #
85
+ # @example Queue API request response time w/ source
86
+ # queue.time :api_request_time, :source => 'app1' do
87
+ # # API request..
88
+ # end
89
+ #
90
+ # @param [Symbol|String] name Metric name
91
+ # @param [Hash] options Metric options
92
+ def time(name, options={})
93
+ start = Time.now
94
+ yield
95
+ duration = (Time.now - start) * 1000.0 # milliseconds
96
+ metric = {name => options.merge({:value => duration})}
97
+ add metric
98
+ end
99
+ alias :benchmark :time
100
+
101
+ private
102
+
103
+ def create_persister
104
+ type = Simple.persistence.capitalize
105
+ Librato::Metrics::Persistence.const_get(type).new
106
+ end
107
+
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,100 @@
1
+ module Librato
2
+ module Metrics
3
+
4
+ # Class-level methods for quick one-off submission of metrics.
5
+ #
6
+ # @example Send a quick metric
7
+ # Librato::Metrics::Simple.authenticate 'fred@foo.com', 'myapikey'
8
+ # Librato::Metrics::Simple.save :total_vists => {:type => counter, :value => 2311}
9
+ #
10
+ # For more than quick one-off use, take a look at {Queue}. For
11
+ # convenience, most of Simple's methods can be accessed directly from
12
+ # the {Metrics} module.
13
+ #
14
+ class Simple
15
+
16
+ class << self
17
+ # class instance vars
18
+ attr_accessor :email, :api_key
19
+
20
+ # API endpoint to use for queries and direct
21
+ # persistence.
22
+ #
23
+ # @return [String] api_endpoint
24
+ def api_endpoint
25
+ @api_endpoint ||= 'https://metrics-api.librato.com/v1/'
26
+ end
27
+
28
+ # Set API endpoint for use with queries and direct
29
+ # persistence. Generally you should not need to set this
30
+ # as it will default to the current Librato Metrics
31
+ # endpoint.
32
+ #
33
+ def api_endpoint=(endpoint)
34
+ @api_endpoint = endpoint
35
+ end
36
+
37
+ # Authenticate for direct persistence
38
+ #
39
+ # @param [String] email
40
+ # @param [String] api_key
41
+ def authenticate(email, api_key)
42
+ flush_authentication
43
+ self.email, self.api_key = email, api_key
44
+ end
45
+
46
+ def connection
47
+ @connection ||= Excon.new(self.api_endpoint, :headers => {'Authorization' => auth_header})
48
+ end
49
+
50
+ # Purge current credentials and connection
51
+ #
52
+ def flush_authentication
53
+ self.email = nil
54
+ self.api_key = nil
55
+ @connection = nil
56
+ end
57
+
58
+ # Persistence type to use when saving metrics.
59
+ # Default is :direct.
60
+ #
61
+ def persistence
62
+ @persistence ||= :direct
63
+ end
64
+
65
+ # Set persistence type to use when saving metrics.
66
+ #
67
+ # @param [Symbol] persistence_type
68
+ def persistence=(persist_method)
69
+ @persistence = persist_method
70
+ end
71
+
72
+ def persister
73
+ @queue ? @queue.persister : nil
74
+ end
75
+
76
+ # Submit all queued metrics
77
+ #
78
+ def submit(args)
79
+ @queue ||= Queue.new
80
+ @queue.add args
81
+ @queue.submit
82
+ end
83
+
84
+ private
85
+
86
+ def auth_header
87
+ raise CredentialsMissing unless (self.email and self.api_key)
88
+ encoded = Base64.encode64("#{email}:#{api_key}").gsub("\n", ' ')
89
+ "Basic #{encoded}"
90
+ end
91
+
92
+ def flush_persistence
93
+ @persistence = nil
94
+ end
95
+
96
+ end
97
+
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,5 @@
1
+ module Librato
2
+ module Metrics
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,36 @@
1
+ lib = File.expand_path('../lib/', __FILE__)
2
+ $:.unshift lib unless $:.include?(lib)
3
+
4
+ require 'librato/metrics/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.specification_version = 2 if s.respond_to? :specification_version=
8
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
9
+ s.rubygems_version = '1.3.5'
10
+
11
+ s.name = 'librato-metrics'
12
+ s.version = Librato::Metrics::VERSION
13
+
14
+ s.summary = "Ruby wrapper for Librato's Metrics API"
15
+ s.description = "An easy to use ruby wrapper for Librato's Metrics API"
16
+
17
+ s.authors = ["Matt Sanders"]
18
+ s.email = 'matt@librato.com'
19
+ s.homepage = 'http://metrics.librato.com'
20
+
21
+ s.require_paths = %w[lib]
22
+
23
+ s.rdoc_options = ["--charset=UTF-8"]
24
+ s.extra_rdoc_files = %w[LICENSE]
25
+
26
+ ## runtime dependencies
27
+ s.add_dependency 'excon', '~>0.7.12'
28
+
29
+ ## development dependencies
30
+ s.add_development_dependency 'rspec', '~>2.6.0'
31
+ s.add_development_dependency 'yard'
32
+ s.add_development_dependency 'rdiscount' # for yard
33
+
34
+ s.files = `git ls-files`.split("\n")
35
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
36
+ end
@@ -0,0 +1,10 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+
3
+ require 'rspec'
4
+ require 'rspec/mocks/standalone'
5
+
6
+ require 'librato/metrics'
7
+
8
+ RSpec.configure do |config|
9
+
10
+ end
@@ -0,0 +1,146 @@
1
+ require "spec_helper.rb"
2
+
3
+ module Librato
4
+ module Metrics
5
+
6
+ describe Queue do
7
+
8
+ describe "#add" do
9
+
10
+ context "with single hash argument" do
11
+ it "should record a key-value gauge" do
12
+ subject.add :foo => 3000
13
+ subject.queued.should eql({:gauges => [{:name => 'foo', :value => 3000}]})
14
+ end
15
+ end
16
+
17
+ context "with specified metric type" do
18
+ it "should record counters" do
19
+ subject.add :total_visits => {:type => :counter, :value => 4000}
20
+ expected = {:counters => [{:name => 'total_visits', :value => 4000}]}
21
+ subject.queued.should eql expected
22
+ end
23
+
24
+ it "should record gauges" do
25
+ subject.add :temperature => {:type => :gauge, :value => 34}
26
+ expected = {:gauges => [{:name => 'temperature', :value => 34}]}
27
+ subject.queued.should eql expected
28
+ end
29
+ end
30
+
31
+ context "with extra attributes" do
32
+ it "should record" do
33
+ measure_time = Time.now
34
+ subject.add :disk_use => {:value => 35.4, :period => 2,
35
+ :description => 'current disk utilization', :measure_time => measure_time,
36
+ :source => 'db2'}
37
+ expected = {:gauges => [{:value => 35.4, :name => 'disk_use', :period => 2,
38
+ :description => 'current disk utilization', :measure_time => measure_time,
39
+ :source => 'db2'}]}
40
+ subject.queued.should eql expected
41
+ end
42
+ end
43
+
44
+ context "with multiple metrics" do
45
+ it "should record" do
46
+ subject.add :foo => 123, :bar => 345, :baz => 567
47
+ expected = {:gauges=>[{:name=>"foo", :value=>123}, {:name=>"bar", :value=>345}, {:name=>"baz", :value=>567}]}
48
+ subject.queued.should eql expected
49
+ end
50
+ end
51
+
52
+ end
53
+
54
+ describe "#counters" do
55
+
56
+ it "should return currently queued counters" do
57
+ subject.add :transactions => {:type => :counter, :value => 12345},
58
+ :register_cents => {:type => :gauge, :value => 211101}
59
+ subject.counters.should eql [{:name => 'transactions', :value => 12345}]
60
+ end
61
+
62
+ it "should return [] when no queued counters" do
63
+ subject.counters.should eql []
64
+ end
65
+
66
+ end
67
+
68
+ describe "#gauges" do
69
+
70
+ it "should return currently queued gauges" do
71
+ subject.add :transactions => {:type => :counter, :value => 12345},
72
+ :register_cents => {:type => :gauge, :value => 211101}
73
+ subject.gauges.should eql [{:name => 'register_cents', :value => 211101}]
74
+ end
75
+
76
+ it "should return [] when no queued gauges" do
77
+ subject.gauges.should eql []
78
+ end
79
+
80
+ end
81
+
82
+ describe "#submit" do
83
+
84
+ before(:all) do
85
+ Librato::Metrics.authenticate 'me@librato.com', 'foo'
86
+ Librato::Metrics.persistence = :test
87
+ end
88
+ after(:all) { Librato::Metrics::Simple.flush_authentication }
89
+
90
+ context "when successful" do
91
+ it "should flush queued metrics and return true" do
92
+ subject.add :steps => 2042, :distance => 1234
93
+ subject.submit.should be_true
94
+ subject.queued.should be_empty
95
+ end
96
+ end
97
+
98
+ context "when failed" do
99
+ it "should preserve queue and return false" do
100
+ subject.add :steps => 2042, :distance => 1234
101
+ subject.persister.return_value(false)
102
+ subject.submit.should be_false
103
+ subject.queued.should_not be_empty
104
+ end
105
+ end
106
+
107
+ end
108
+
109
+ describe "#time" do
110
+
111
+ context "with metric name only" do
112
+
113
+ it "should queue metric with timed value" do
114
+ subject.time :sleeping do
115
+ sleep 0.1
116
+ end
117
+ queued = subject.queued[:gauges][0]
118
+ queued[:name].should == 'sleeping'
119
+ queued[:value].should be > 100
120
+ queued[:value].should be_within(30).of(100)
121
+ end
122
+
123
+ end
124
+
125
+ context "with metric and options" do
126
+
127
+ it "should queue metric with value and options" do
128
+ subject.time :sleep_two, :source => 'app1', :period => 2 do
129
+ sleep 0.05
130
+ end
131
+ queued = subject.queued[:gauges][0]
132
+ queued[:name].should == 'sleep_two'
133
+ queued[:period].should == 2
134
+ queued[:source].should == 'app1'
135
+ queued[:value].should be > 50
136
+ queued[:value].should be_within(30).of(50)
137
+ end
138
+
139
+ end
140
+
141
+ end
142
+
143
+ end # MetricSet
144
+
145
+ end
146
+ end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ module Librato
4
+ module Metrics
5
+
6
+ describe Simple do
7
+
8
+ describe "#api_endpoint" do
9
+ it "should default to metrics" do
10
+ Simple.api_endpoint.should == 'https://metrics-api.librato.com/v1/'
11
+ end
12
+ end
13
+
14
+ describe "#api_endpoint=" do
15
+ it "should set api_endpoint" do
16
+ @prior = Simple.api_endpoint
17
+ Simple.api_endpoint = 'http://test.com/'
18
+ Simple.api_endpoint.should == 'http://test.com/'
19
+ Simple.api_endpoint = @prior
20
+ end
21
+
22
+ # TODO:
23
+ # it "should ensure trailing slash"
24
+ # it "should ensure real URI"
25
+ end
26
+
27
+ describe "#authenticate" do
28
+ context "when given two arguments" do
29
+ it "should store them as email and api_key" do
30
+ Simple.authenticate 'test@librato.com', 'api_key'
31
+ Simple.email.should == 'test@librato.com'
32
+ Simple.api_key.should == 'api_key'
33
+ end
34
+ end
35
+ end
36
+
37
+ describe "#connection" do
38
+ it "should raise exception without authentication" do
39
+ Simple.flush_authentication
40
+ lambda{ Simple.connection }.should raise_error(Librato::Metrics::CredentialsMissing)
41
+ end
42
+ end
43
+
44
+ describe "#persistence" do
45
+ it "should default to direct" do
46
+ Simple.send(:flush_persistence)
47
+ Simple.persistence.should == :direct
48
+ end
49
+
50
+ it "should allow configuration of persistence method" do
51
+ current = Simple.persistence
52
+ Simple.persistence = :fake
53
+ Simple.persistence.should == :fake
54
+ Simple.persistence = current
55
+ end
56
+ end
57
+
58
+ describe "#submit" do
59
+ before(:all) do
60
+ Simple.persistence = :test
61
+ Simple.authenticate 'me@librato.com', 'foo'
62
+ end
63
+ after(:all) { Simple.flush_authentication }
64
+
65
+ it "should persist metrics immediately" do
66
+ Simple.persistence = :test
67
+ Simple.submit(:foo => 123).should eql true
68
+ Simple.persister.persisted.should eql({:gauges => [{:name => 'foo', :value => 123}]})
69
+ end
70
+
71
+ it "should tolerate muliple metrics" do
72
+ lambda{ Simple.submit :foo => 123, :bar => 456 }.should_not raise_error
73
+ expected = {:gauges => [{:name => 'foo', :value => 123}, {:name => 'bar', :value => 456}]}
74
+ Simple.persister.persisted.should eql expected
75
+ end
76
+ end
77
+
78
+ end
79
+
80
+ end
81
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ module Librato
4
+
5
+ describe Metrics do
6
+
7
+ describe "#authorize" do
8
+
9
+ context "when given two arguments" do
10
+ it "should store them on simple" do
11
+ Metrics.authenticate 'tester@librato.com', 'api_key'
12
+ Metrics::Simple.email.should == 'tester@librato.com'
13
+ Metrics::Simple.api_key.should == 'api_key'
14
+ end
15
+ end
16
+
17
+ end
18
+
19
+ describe "#list" do
20
+
21
+ context "without arguments" do
22
+
23
+ it "should list all metrics"
24
+
25
+ end
26
+
27
+ context "with a name argument" do
28
+
29
+ it "should list metrics that match"
30
+
31
+ end
32
+
33
+ end
34
+
35
+ describe "#persistence" do
36
+
37
+ it "should allow configuration of persistence method" do
38
+ Metrics.persistence = :test
39
+ Metrics.persistence.should == :test
40
+ end
41
+
42
+ end
43
+
44
+ describe "#submit" do
45
+ before(:all) do
46
+ Librato::Metrics.persistence = :test
47
+ Librato::Metrics.authenticate 'me@librato.com', 'foo'
48
+ end
49
+ after(:all) { Librato::Metrics::Simple.flush_authentication }
50
+
51
+ it "should persist metrics immediately" do
52
+ Metrics.persistence = :test
53
+ Metrics.submit(:foo => 123).should eql true
54
+ Metrics.persister.persisted.should eql({:gauges => [{:name => 'foo', :value => 123}]})
55
+ end
56
+
57
+ it "should tolerate multiple metrics" do
58
+ lambda{ Librato::Metrics.submit :foo => 123, :bar => 456 }.should_not raise_error
59
+ expected = {:gauges => [{:name => 'foo', :value => 123}, {:name => 'bar', :value => 456}]}
60
+ Librato::Metrics.persister.persisted.should eql expected
61
+ end
62
+
63
+ end
64
+
65
+ end
66
+
67
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: librato-metrics
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Matt Sanders
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-08 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: excon
16
+ requirement: &70180001393620 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.7.12
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70180001393620
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &70180001393140 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 2.6.0
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70180001393140
36
+ - !ruby/object:Gem::Dependency
37
+ name: yard
38
+ requirement: &70180001392760 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70180001392760
47
+ - !ruby/object:Gem::Dependency
48
+ name: rdiscount
49
+ requirement: &70180001392300 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70180001392300
58
+ description: An easy to use ruby wrapper for Librato's Metrics API
59
+ email: matt@librato.com
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files:
63
+ - LICENSE
64
+ files:
65
+ - .gitignore
66
+ - Gemfile
67
+ - LICENSE
68
+ - README.md
69
+ - Rakefile
70
+ - lib/librato/metrics.rb
71
+ - lib/librato/metrics/errors.rb
72
+ - lib/librato/metrics/persistence.rb
73
+ - lib/librato/metrics/persistence/direct.rb
74
+ - lib/librato/metrics/persistence/test.rb
75
+ - lib/librato/metrics/queue.rb
76
+ - lib/librato/metrics/simple.rb
77
+ - lib/librato/metrics/version.rb
78
+ - librato-metrics.gemspec
79
+ - spec/spec_helper.rb
80
+ - spec/unit/metrics/queue_spec.rb
81
+ - spec/unit/metrics/simple_spec.rb
82
+ - spec/unit/metrics_spec.rb
83
+ homepage: http://metrics.librato.com
84
+ licenses: []
85
+ post_install_message:
86
+ rdoc_options:
87
+ - --charset=UTF-8
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project:
104
+ rubygems_version: 1.8.10
105
+ signing_key:
106
+ specification_version: 2
107
+ summary: Ruby wrapper for Librato's Metrics API
108
+ test_files:
109
+ - spec/spec_helper.rb
110
+ - spec/unit/metrics/queue_spec.rb
111
+ - spec/unit/metrics/simple_spec.rb
112
+ - spec/unit/metrics_spec.rb
113
+ has_rdoc: