librato-metrics 1.6.2 → 2.0.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +2 -0
- data/.rspec +2 -1
- data/.travis.yml +2 -3
- data/CHANGELOG.md +6 -2
- data/Gemfile +3 -2
- data/README.md +33 -33
- data/Rakefile +3 -4
- data/certs/librato-public.pem +18 -18
- data/examples/simple.rb +5 -5
- data/lib/librato/metrics.rb +9 -12
- data/lib/librato/metrics/aggregator.rb +6 -6
- data/lib/librato/metrics/annotator.rb +11 -11
- data/lib/librato/metrics/client.rb +24 -91
- data/lib/librato/metrics/connection.rb +2 -2
- data/lib/librato/metrics/middleware/retry.rb +1 -1
- data/lib/librato/metrics/processor.rb +3 -3
- data/lib/librato/metrics/queue.rb +1 -1
- data/lib/librato/metrics/smart_json.rb +27 -16
- data/lib/librato/metrics/version.rb +1 -1
- data/librato-metrics.gemspec +2 -2
- data/spec/integration/metrics/annotator_spec.rb +73 -73
- data/spec/integration/metrics/middleware/count_requests_spec.rb +8 -8
- data/spec/integration/metrics/queue_spec.rb +28 -28
- data/spec/integration/metrics_spec.rb +137 -137
- data/spec/spec_helper.rb +6 -10
- data/spec/unit/metrics/aggregator_spec.rb +130 -130
- data/spec/unit/metrics/client_spec.rb +37 -37
- data/spec/unit/metrics/connection_spec.rb +30 -30
- data/spec/unit/metrics/queue/autosubmission_spec.rb +25 -25
- data/spec/unit/metrics/queue_spec.rb +178 -179
- data/spec/unit/metrics/smart_json_spec.rb +79 -0
- data/spec/unit/metrics_spec.rb +21 -21
- metadata +48 -42
- metadata.gz.sig +0 -0
- data/spec/integration/deprecated_methods_spec.rb +0 -85
data/spec/spec_helper.rb
CHANGED
@@ -11,6 +11,11 @@ require 'librato/metrics'
|
|
11
11
|
|
12
12
|
RSpec.configure do |config|
|
13
13
|
|
14
|
+
# only accept expect syntax instead of should
|
15
|
+
config.expect_with :rspec do |c|
|
16
|
+
c.syntax = :expect
|
17
|
+
end
|
18
|
+
|
14
19
|
# purge all metrics from test account
|
15
20
|
def delete_all_metrics
|
16
21
|
connection = Librato::Metrics.client.connection
|
@@ -65,20 +70,11 @@ RSpec.configure do |config|
|
|
65
70
|
|
66
71
|
end
|
67
72
|
|
68
|
-
# Ex: 'foobar'.should start_with('foo') #=> true
|
69
|
-
#
|
70
|
-
RSpec::Matchers.define :start_with do |start_string|
|
71
|
-
match do |string|
|
72
|
-
start_length = start_string.length
|
73
|
-
string[0..start_length-1] == start_string
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
73
|
# Compares hashes of arrays by converting the arrays to
|
78
74
|
# sets before comparision
|
79
75
|
#
|
80
76
|
# @example
|
81
|
-
# {:
|
77
|
+
# {foo: [1,3,2]}.should equal_unordered({foo: [1,2,3]})
|
82
78
|
RSpec::Matchers.define :equal_unordered do |result|
|
83
79
|
result.each do |key, value|
|
84
80
|
result[key] = value.to_set if value.respond_to?(:to_set)
|
@@ -6,174 +6,174 @@ module Librato
|
|
6
6
|
|
7
7
|
before(:all) do
|
8
8
|
@time = 1354720160 #Time.now.to_i
|
9
|
-
Aggregator.
|
9
|
+
allow_any_instance_of(Aggregator).to receive(:epoch_time).and_return(@time)
|
10
10
|
end
|
11
11
|
|
12
12
|
describe "initialization" do
|
13
13
|
context "with specified client" do
|
14
|
-
it "
|
14
|
+
it "sets to client" do
|
15
15
|
barney = Client.new
|
16
|
-
a = Aggregator.new(:
|
17
|
-
a.client.
|
16
|
+
a = Aggregator.new(client: barney)
|
17
|
+
expect(a.client).to eq(barney)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
21
|
context "without specified client" do
|
22
|
-
it "
|
22
|
+
it "uses Librato::Metrics client" do
|
23
23
|
a = Aggregator.new
|
24
|
-
a.client.
|
24
|
+
expect(a.client).to eq(Librato::Metrics.client)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
28
|
context "with specified source" do
|
29
|
-
it "
|
30
|
-
a = Aggregator.new(:
|
31
|
-
a.source.
|
29
|
+
it "sets to source" do
|
30
|
+
a = Aggregator.new(source: 'rubble')
|
31
|
+
expect(a.source).to eq('rubble')
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
35
|
context "without specified source" do
|
36
|
-
it "
|
36
|
+
it "does not have a source" do
|
37
37
|
a = Aggregator.new
|
38
|
-
a.source.
|
38
|
+
expect(a.source).to be_nil
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
43
|
describe "#add" do
|
44
|
-
it "
|
45
|
-
subject.add(:
|
44
|
+
it "allows chaining" do
|
45
|
+
expect(subject.add(foo: 1234)).to eq(subject)
|
46
46
|
end
|
47
47
|
|
48
48
|
context "with single hash argument" do
|
49
|
-
it "
|
50
|
-
subject.add :
|
51
|
-
expected = {
|
52
|
-
:
|
53
|
-
{ :
|
54
|
-
:
|
55
|
-
:
|
56
|
-
:
|
57
|
-
:
|
49
|
+
it "records a single aggregate" do
|
50
|
+
subject.add foo: 3000
|
51
|
+
expected = { #measure_time: @time, TODO: support specific time
|
52
|
+
gauges: [
|
53
|
+
{ name: 'foo',
|
54
|
+
count: 1,
|
55
|
+
sum: 3000.0,
|
56
|
+
min: 3000.0,
|
57
|
+
max: 3000.0}
|
58
58
|
]
|
59
59
|
}
|
60
|
-
subject.queued.
|
60
|
+
expect(subject.queued).to equal_unordered(expected)
|
61
61
|
end
|
62
62
|
|
63
|
-
it "
|
64
|
-
subject.add :
|
65
|
-
subject.add :
|
66
|
-
subject.add :
|
67
|
-
subject.add :
|
68
|
-
subject.add :
|
69
|
-
expected = { :
|
70
|
-
{ :
|
71
|
-
:
|
72
|
-
:
|
73
|
-
:
|
74
|
-
:
|
63
|
+
it "aggregates multiple measurements" do
|
64
|
+
subject.add foo: 1
|
65
|
+
subject.add foo: 2
|
66
|
+
subject.add foo: 3
|
67
|
+
subject.add foo: 4
|
68
|
+
subject.add foo: 5
|
69
|
+
expected = { gauges: [
|
70
|
+
{ name: 'foo',
|
71
|
+
count: 5,
|
72
|
+
sum: 15.0,
|
73
|
+
min: 1.0,
|
74
|
+
max: 5.0}
|
75
75
|
]
|
76
76
|
}
|
77
|
-
subject.queued.
|
77
|
+
expect(subject.queued).to equal_unordered(expected)
|
78
78
|
end
|
79
79
|
|
80
|
-
it "
|
81
|
-
subject.add :
|
82
|
-
subject.add :
|
83
|
-
subject.add :
|
84
|
-
subject.add :
|
85
|
-
expected = { :
|
86
|
-
{ :
|
87
|
-
:
|
88
|
-
{ :
|
89
|
-
:
|
80
|
+
it "respects source argument" do
|
81
|
+
subject.add foo: {source: 'alpha', value: 1}
|
82
|
+
subject.add foo: 5
|
83
|
+
subject.add foo: {source: :alpha, value: 6}
|
84
|
+
subject.add foo: 10
|
85
|
+
expected = { gauges: [
|
86
|
+
{ name: 'foo', source: 'alpha', count: 2,
|
87
|
+
sum: 7.0, min: 1.0, max: 6.0 },
|
88
|
+
{ name: 'foo', count: 2,
|
89
|
+
sum: 15.0, min: 5.0, max: 10.0 }
|
90
90
|
]}
|
91
|
-
subject.queued.
|
91
|
+
expect(subject.queued).to equal_unordered(expected)
|
92
92
|
end
|
93
93
|
|
94
94
|
context "with a prefix set" do
|
95
|
-
it "
|
96
|
-
subject = Aggregator.new(:
|
97
|
-
subject.add :
|
98
|
-
subject.add :
|
99
|
-
expected = {:
|
100
|
-
{ :
|
101
|
-
:
|
102
|
-
:
|
103
|
-
:
|
104
|
-
:
|
95
|
+
it "auto-prepends names" do
|
96
|
+
subject = Aggregator.new(prefix: 'foo')
|
97
|
+
subject.add bar: 1
|
98
|
+
subject.add bar: 12
|
99
|
+
expected = {gauges: [
|
100
|
+
{ name:'foo.bar',
|
101
|
+
count: 2,
|
102
|
+
sum: 13.0,
|
103
|
+
min: 1.0,
|
104
|
+
max: 12.0
|
105
105
|
}
|
106
106
|
]
|
107
107
|
}
|
108
|
-
subject.queued.
|
108
|
+
expect(subject.queued).to equal_unordered(expected)
|
109
109
|
end
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
113
113
|
context "with multiple hash arguments" do
|
114
|
-
it "
|
115
|
-
subject.add :
|
116
|
-
subject.add :
|
114
|
+
it "records a single aggregate" do
|
115
|
+
subject.add foo: 3000
|
116
|
+
subject.add bar: 30
|
117
117
|
expected = {
|
118
|
-
|
119
|
-
:
|
120
|
-
{ :
|
121
|
-
:
|
122
|
-
:
|
123
|
-
:
|
124
|
-
:
|
125
|
-
{ :
|
126
|
-
:
|
127
|
-
:
|
128
|
-
:
|
129
|
-
:
|
118
|
+
#measure_time: @time, TODO: support specific time
|
119
|
+
gauges: [
|
120
|
+
{ name: 'foo',
|
121
|
+
count: 1,
|
122
|
+
sum: 3000.0,
|
123
|
+
min: 3000.0,
|
124
|
+
max: 3000.0},
|
125
|
+
{ name: 'bar',
|
126
|
+
count: 1,
|
127
|
+
sum: 30.0,
|
128
|
+
min: 30.0,
|
129
|
+
max: 30.0},
|
130
130
|
]
|
131
131
|
}
|
132
|
-
subject.queued.
|
132
|
+
expect(subject.queued).to equal_unordered(expected)
|
133
133
|
end
|
134
134
|
|
135
|
-
it "
|
136
|
-
subject.add :
|
137
|
-
subject.add :
|
138
|
-
subject.add :
|
139
|
-
subject.add :
|
140
|
-
subject.add :
|
141
|
-
|
142
|
-
subject.add :
|
143
|
-
subject.add :
|
144
|
-
subject.add :
|
145
|
-
subject.add :
|
146
|
-
subject.add :
|
147
|
-
expected = { :
|
148
|
-
{ :
|
149
|
-
:
|
150
|
-
:
|
151
|
-
:
|
152
|
-
:
|
153
|
-
{ :
|
154
|
-
:
|
155
|
-
:
|
156
|
-
:
|
157
|
-
:
|
135
|
+
it "aggregates multiple measurements" do
|
136
|
+
subject.add foo: 1
|
137
|
+
subject.add foo: 2
|
138
|
+
subject.add foo: 3
|
139
|
+
subject.add foo: 4
|
140
|
+
subject.add foo: 5
|
141
|
+
|
142
|
+
subject.add bar: 6
|
143
|
+
subject.add bar: 7
|
144
|
+
subject.add bar: 8
|
145
|
+
subject.add bar: 9
|
146
|
+
subject.add bar: 10
|
147
|
+
expected = { gauges: [
|
148
|
+
{ name: 'foo',
|
149
|
+
count: 5,
|
150
|
+
sum: 15.0,
|
151
|
+
min: 1.0,
|
152
|
+
max: 5.0},
|
153
|
+
{ name: 'bar',
|
154
|
+
count: 5,
|
155
|
+
sum: 40.0,
|
156
|
+
min: 6.0,
|
157
|
+
max: 10.0}
|
158
158
|
]
|
159
159
|
}
|
160
|
-
subject.queued.
|
160
|
+
expect(subject.queued).to equal_unordered(expected)
|
161
161
|
end
|
162
162
|
end
|
163
163
|
end
|
164
164
|
|
165
165
|
describe "#queued" do
|
166
|
-
it "
|
167
|
-
a = Aggregator.new(:
|
168
|
-
a.add :
|
169
|
-
a.queued[:source].
|
166
|
+
it "includes global source if set" do
|
167
|
+
a = Aggregator.new(source: 'blah')
|
168
|
+
a.add foo: 12
|
169
|
+
expect(a.queued[:source]).to eq('blah')
|
170
170
|
end
|
171
171
|
|
172
|
-
it "
|
172
|
+
it "includes global measure_time if set" do
|
173
173
|
measure_time = (Time.now-1000).to_i
|
174
|
-
a = Aggregator.new(:
|
175
|
-
a.add :
|
176
|
-
a.queued[:measure_time].
|
174
|
+
a = Aggregator.new(measure_time: measure_time)
|
175
|
+
a.add foo: 12
|
176
|
+
expect(a.queued[:measure_time]).to eq(measure_time)
|
177
177
|
end
|
178
178
|
end
|
179
179
|
|
@@ -184,44 +184,44 @@ module Librato
|
|
184
184
|
end
|
185
185
|
|
186
186
|
context "when successful" do
|
187
|
-
it "
|
188
|
-
subject.add :
|
189
|
-
subject.submit.
|
190
|
-
subject.empty
|
187
|
+
it "flushes queued metrics and return true" do
|
188
|
+
subject.add steps: 2042, distance: 1234
|
189
|
+
expect(subject.submit).to be true
|
190
|
+
expect(subject.empty?).to be true
|
191
191
|
end
|
192
192
|
end
|
193
193
|
|
194
194
|
context "when failed" do
|
195
|
-
it "
|
196
|
-
subject.add :
|
195
|
+
it "preserves queue and return false" do
|
196
|
+
subject.add steps: 2042, distance: 1234
|
197
197
|
subject.persister.return_value(false)
|
198
|
-
subject.submit.
|
199
|
-
subject.empty
|
198
|
+
expect(subject.submit).to be false
|
199
|
+
expect(subject.empty?).to be false
|
200
200
|
end
|
201
201
|
end
|
202
202
|
end
|
203
203
|
|
204
204
|
describe "#time" do
|
205
205
|
context "with metric name only" do
|
206
|
-
it "
|
206
|
+
it "queues metric with timed value" do
|
207
207
|
1.upto(5) do
|
208
208
|
subject.time :sleeping do
|
209
209
|
sleep 0.1
|
210
210
|
end
|
211
211
|
end
|
212
212
|
queued = subject.queued[:gauges][0]
|
213
|
-
queued[:name].
|
214
|
-
queued[:count].
|
215
|
-
queued[:sum].
|
216
|
-
queued[:sum].
|
213
|
+
expect(queued[:name]).to eq('sleeping')
|
214
|
+
expect(queued[:count]).to eq(5)
|
215
|
+
expect(queued[:sum]).to be >= 500.0
|
216
|
+
expect(queued[:sum]).to be_within(150).of(500)
|
217
217
|
end
|
218
218
|
|
219
|
-
it "
|
219
|
+
it "returns the result of the block" do
|
220
220
|
result = subject.time :returning do
|
221
221
|
:hi_there
|
222
222
|
end
|
223
223
|
|
224
|
-
result.
|
224
|
+
expect(result).to eq(:hi_there)
|
225
225
|
end
|
226
226
|
end
|
227
227
|
end
|
@@ -233,18 +233,18 @@ module Librato
|
|
233
233
|
client
|
234
234
|
end
|
235
235
|
|
236
|
-
it "
|
237
|
-
timed_agg = Aggregator.new(:
|
238
|
-
timed_agg.add :
|
239
|
-
timed_agg.persister.persisted.
|
236
|
+
it "does not submit immediately" do
|
237
|
+
timed_agg = Aggregator.new(client: client, autosubmit_interval: 1)
|
238
|
+
timed_agg.add foo: 1
|
239
|
+
expect(timed_agg.persister.persisted).to be_nil # nothing sent
|
240
240
|
end
|
241
241
|
|
242
|
-
it "
|
243
|
-
timed_agg = Aggregator.new(:
|
244
|
-
timed_agg.add :
|
242
|
+
it "submits after interval" do
|
243
|
+
timed_agg = Aggregator.new(client: client, autosubmit_interval: 1)
|
244
|
+
timed_agg.add foo: 1
|
245
245
|
sleep 1
|
246
|
-
timed_agg.add :
|
247
|
-
timed_agg.persister.persisted.
|
246
|
+
timed_agg.add foo: 2
|
247
|
+
expect(timed_agg.persister.persisted).not_to be_nil # sent
|
248
248
|
end
|
249
249
|
end
|
250
250
|
|
@@ -7,43 +7,43 @@ module Librato
|
|
7
7
|
|
8
8
|
describe "#agent_identifier" do
|
9
9
|
context "when given a single string argument" do
|
10
|
-
it "
|
10
|
+
it "sets agent_identifier" do
|
11
11
|
subject.agent_identifier 'mycollector/0.1 (dev_id:foo)'
|
12
|
-
subject.agent_identifier.
|
12
|
+
expect(subject.agent_identifier).to eq('mycollector/0.1 (dev_id:foo)')
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
context "when given three arguments" do
|
17
|
-
it "
|
17
|
+
it "composes an agent string" do
|
18
18
|
subject.agent_identifier('test_app', '0.5', 'foobar')
|
19
|
-
subject.agent_identifier.
|
19
|
+
expect(subject.agent_identifier).to eq('test_app/0.5 (dev_id:foobar)')
|
20
20
|
end
|
21
21
|
|
22
22
|
context "when given an empty string" do
|
23
|
-
it "
|
23
|
+
it "sets to empty" do
|
24
24
|
subject.agent_identifier ''
|
25
|
-
subject.agent_identifier.
|
25
|
+
expect(subject.agent_identifier).to be_empty
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
30
|
context "when given two arguments" do
|
31
|
-
it "
|
32
|
-
|
31
|
+
it "raises error" do
|
32
|
+
expect { subject.agent_identifier('test_app', '0.5') }.to raise_error(ArgumentError)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
37
|
describe "#api_endpoint" do
|
38
|
-
it "
|
39
|
-
subject.api_endpoint.
|
38
|
+
it "defaults to metrics" do
|
39
|
+
expect(subject.api_endpoint).to eq('https://metrics-api.librato.com')
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
43
|
describe "#api_endpoint=" do
|
44
|
-
it "
|
44
|
+
it "sets api_endpoint" do
|
45
45
|
subject.api_endpoint = 'http://test.com/'
|
46
|
-
subject.api_endpoint.
|
46
|
+
expect(subject.api_endpoint).to eq('http://test.com/')
|
47
47
|
end
|
48
48
|
|
49
49
|
# TODO:
|
@@ -53,71 +53,71 @@ module Librato
|
|
53
53
|
|
54
54
|
describe "#authenticate" do
|
55
55
|
context "when given two arguments" do
|
56
|
-
it "
|
56
|
+
it "stores them as email and api_key" do
|
57
57
|
subject.authenticate 'test@librato.com', 'api_key'
|
58
|
-
subject.email.
|
59
|
-
subject.api_key.
|
58
|
+
expect(subject.email).to eq('test@librato.com')
|
59
|
+
expect(subject.api_key).to eq('api_key')
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
64
|
describe "#connection" do
|
65
|
-
it "
|
65
|
+
it "raises exception without authentication" do
|
66
66
|
subject.flush_authentication
|
67
|
-
|
67
|
+
expect { subject.connection }.to raise_error(Librato::Metrics::CredentialsMissing)
|
68
68
|
end
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
describe "#faraday_adapter" do
|
72
|
-
it "
|
72
|
+
it "defaults to Metrics default adapter" do
|
73
73
|
Metrics.faraday_adapter = :typhoeus
|
74
|
-
Client.new.faraday_adapter.
|
74
|
+
expect(Client.new.faraday_adapter).to eq(Metrics.faraday_adapter)
|
75
75
|
Metrics.faraday_adapter = nil
|
76
76
|
end
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
describe "#faraday_adapter=" do
|
80
|
-
it "
|
80
|
+
it "allows setting of faraday adapter" do
|
81
81
|
subject.faraday_adapter = :excon
|
82
|
-
subject.faraday_adapter.
|
82
|
+
expect(subject.faraday_adapter).to eq(:excon)
|
83
83
|
subject.faraday_adapter = :patron
|
84
|
-
subject.faraday_adapter.
|
84
|
+
expect(subject.faraday_adapter).to eq(:patron)
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
88
|
describe "#new_queue" do
|
89
|
-
it "
|
89
|
+
it "returns a new queue with client set" do
|
90
90
|
queue = subject.new_queue
|
91
|
-
queue.client.
|
91
|
+
expect(queue.client).to eq(subject)
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
95
|
describe "#persistence" do
|
96
|
-
it "
|
96
|
+
it "defaults to direct" do
|
97
97
|
subject.send(:flush_persistence)
|
98
|
-
subject.persistence.
|
98
|
+
expect(subject.persistence).to eq(:direct)
|
99
99
|
end
|
100
100
|
|
101
|
-
it "
|
101
|
+
it "allows configuration of persistence method" do
|
102
102
|
subject.persistence = :fake
|
103
|
-
subject.persistence.
|
103
|
+
expect(subject.persistence).to eq(:fake)
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
107
|
describe "#submit" do
|
108
|
-
it "
|
108
|
+
it "persists metrics immediately" do
|
109
109
|
subject.authenticate 'me@librato.com', 'foo'
|
110
110
|
subject.persistence = :test
|
111
|
-
subject.submit(:
|
112
|
-
subject.persister.persisted.
|
111
|
+
expect(subject.submit(foo: 123)).to be true
|
112
|
+
expect(subject.persister.persisted).to eq({gauges: [{name: 'foo', value: 123}]})
|
113
113
|
end
|
114
114
|
|
115
|
-
it "
|
115
|
+
it "tolerates muliple metrics" do
|
116
116
|
subject.authenticate 'me@librato.com', 'foo'
|
117
117
|
subject.persistence = :test
|
118
|
-
|
119
|
-
expected = {:
|
120
|
-
subject.persister.persisted.
|
118
|
+
expect { subject.submit foo: 123, bar: 456 }.not_to raise_error
|
119
|
+
expected = {gauges: [{name: 'foo', value: 123}, {name: 'bar', value: 456}]}
|
120
|
+
expect(subject.persister.persisted).to equal_unordered(expected)
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|