librato-metrics 2.0.2 → 2.1.0.beta
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.tar.gz.sig +0 -0
- data/CHANGELOG.md +2 -2
- data/lib/librato/metrics.rb +11 -11
- data/lib/librato/metrics/aggregator.rb +38 -22
- data/lib/librato/metrics/client.rb +34 -0
- data/lib/librato/metrics/errors.rb +1 -0
- data/lib/librato/metrics/middleware/expects_status.rb +9 -18
- data/lib/librato/metrics/persistence/direct.rb +17 -9
- data/lib/librato/metrics/processor.rb +27 -2
- data/lib/librato/metrics/queue.rb +44 -14
- data/lib/librato/metrics/util.rb +25 -0
- data/lib/librato/metrics/version.rb +1 -1
- data/spec/integration/metrics/queue_spec.rb +21 -1
- data/spec/integration/metrics_spec.rb +11 -0
- data/spec/unit/metrics/aggregator_spec.rb +164 -1
- data/spec/unit/metrics/queue_spec.rb +207 -5
- data/spec/unit/metrics/util_spec.rb +23 -0
- metadata +8 -5
- metadata.gz.sig +2 -3
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.md
CHANGED
data/lib/librato/metrics.rb
CHANGED
@@ -13,6 +13,7 @@ require 'metrics/errors'
|
|
13
13
|
require 'metrics/persistence'
|
14
14
|
require 'metrics/queue'
|
15
15
|
require 'metrics/smart_json'
|
16
|
+
require 'metrics/util'
|
16
17
|
require 'metrics/version'
|
17
18
|
|
18
19
|
module Librato
|
@@ -65,23 +66,22 @@ module Librato
|
|
65
66
|
extend SingleForwardable
|
66
67
|
|
67
68
|
TYPES = [:counter, :gauge]
|
68
|
-
PLURAL_TYPES =
|
69
|
+
PLURAL_TYPES = TYPES.map { |type| "#{type}s".to_sym }
|
69
70
|
MIN_MEASURE_TIME = (Time.now-(3600*24*365)).to_i
|
70
71
|
|
71
72
|
# Most of the singleton methods of Librato::Metrics are actually
|
72
73
|
# being called on a global Client instance. See further docs on
|
73
74
|
# Client.
|
74
75
|
#
|
75
|
-
def_delegators
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
:create_snapshot, :get_snapshot
|
76
|
+
def_delegators :client, :agent_identifier, :annotate,
|
77
|
+
:api_endpoint, :api_endpoint=, :authenticate,
|
78
|
+
:connection, :create_snapshot, :delete_metrics,
|
79
|
+
:faraday_adapter, :faraday_adapter=, :get_composite,
|
80
|
+
:get_measurements, :get_metric, :get_series,
|
81
|
+
:get_snapshot, :get_source, :metrics,
|
82
|
+
:persistence, :persistence=, :persister, :proxy, :proxy=,
|
83
|
+
:sources, :submit, :update_metric, :update_metrics,
|
84
|
+
:update_source
|
85
85
|
|
86
86
|
# The Librato::Metrics::Client being used by module-level
|
87
87
|
# access.
|
@@ -23,7 +23,7 @@ module Librato
|
|
23
23
|
# queue.merge!(aggregator)
|
24
24
|
#
|
25
25
|
class Aggregator
|
26
|
-
|
26
|
+
SEPARATOR = '%%' # must not be in valid tags and/or source criteria
|
27
27
|
|
28
28
|
include Processor
|
29
29
|
|
@@ -52,20 +52,29 @@ module Librato
|
|
52
52
|
# @return [Aggregator] returns self
|
53
53
|
def add(measurements)
|
54
54
|
measurements.each do |metric, data|
|
55
|
+
entry = {}
|
55
56
|
if @prefix
|
56
57
|
metric = "#{@prefix}.#{metric}"
|
57
58
|
end
|
59
|
+
entry[:name] = metric.to_s
|
58
60
|
if data.respond_to?(:each) # hash form
|
61
|
+
validate_parameters(data)
|
59
62
|
value = data[:value]
|
60
63
|
if data[:source]
|
61
|
-
metric = "#{metric}#{
|
64
|
+
metric = "#{metric}#{SEPARATOR}#{data[:source]}"
|
65
|
+
entry[:source] = data[:source].to_s
|
66
|
+
elsif data[:tags] && data[:tags].respond_to?(:each)
|
67
|
+
metric = Librato::Metrics::Util.build_key_for(metric.to_s, data[:tags])
|
68
|
+
entry[:tags] = data[:tags]
|
62
69
|
end
|
63
70
|
else
|
64
71
|
value = data
|
65
72
|
end
|
66
73
|
|
67
|
-
@aggregated[metric]
|
68
|
-
@aggregated[metric]
|
74
|
+
@aggregated[metric] = {} unless @aggregated[metric]
|
75
|
+
@aggregated[metric][:aggregate] ||= Aggregate.new
|
76
|
+
@aggregated[metric][:aggregate] << value
|
77
|
+
@aggregated[metric].merge!(entry)
|
69
78
|
end
|
70
79
|
autosubmit_check
|
71
80
|
self
|
@@ -88,31 +97,38 @@ module Librato
|
|
88
97
|
# Returns currently queued data
|
89
98
|
#
|
90
99
|
def queued
|
91
|
-
|
100
|
+
entries = []
|
101
|
+
multidimensional = has_tags?
|
92
102
|
|
93
|
-
@aggregated.
|
94
|
-
source = nil
|
95
|
-
metric = metric.to_s
|
96
|
-
if metric.include?(SOURCE_SEPARATOR)
|
97
|
-
metric, source = metric.split(SOURCE_SEPARATOR)
|
98
|
-
end
|
103
|
+
@aggregated.each_value do |data|
|
99
104
|
entry = {
|
100
|
-
name:
|
101
|
-
count: data.count,
|
102
|
-
sum: data.sum,
|
103
|
-
|
105
|
+
name: data[:name],
|
106
|
+
count: data[:aggregate].count,
|
107
|
+
sum: data[:aggregate].sum,
|
104
108
|
# TODO: make float/non-float consistent in the gem
|
105
|
-
min: data.min.to_f,
|
106
|
-
max: data.max.to_f
|
109
|
+
min: data[:aggregate].min.to_f,
|
110
|
+
max: data[:aggregate].max.to_f
|
107
111
|
# TODO: expose v.sum2 and include
|
108
112
|
}
|
109
|
-
|
110
|
-
|
113
|
+
if data[:source]
|
114
|
+
entry[:source] = data[:source]
|
115
|
+
elsif data[:tags]
|
116
|
+
multidimensional = true
|
117
|
+
entry[:tags] = data[:tags]
|
118
|
+
end
|
119
|
+
multidimensional = true if data[:time]
|
120
|
+
entries << entry
|
111
121
|
end
|
112
|
-
|
113
|
-
req =
|
122
|
+
time = multidimensional ? :time : :measure_time
|
123
|
+
req =
|
124
|
+
if multidimensional
|
125
|
+
{ measurements: entries }
|
126
|
+
else
|
127
|
+
{ gauges: entries }
|
128
|
+
end
|
114
129
|
req[:source] = @source if @source
|
115
|
-
req[:
|
130
|
+
req[:tags] = @tags if has_tags?
|
131
|
+
req[time] = @time if @time
|
116
132
|
|
117
133
|
req
|
118
134
|
end
|
@@ -178,6 +178,40 @@ module Librato
|
|
178
178
|
parsed
|
179
179
|
end
|
180
180
|
|
181
|
+
# Retrieve series of measurements for a given metric
|
182
|
+
#
|
183
|
+
# @example Get series for metric
|
184
|
+
# series = Librato::Metrics.get_series :requests, resolution: 1, duration: 3600
|
185
|
+
#
|
186
|
+
# @example Get series for metric grouped by tag
|
187
|
+
# query = { duration: 3600, resolution: 1, group_by: "environment", group_by_function: "sum" }
|
188
|
+
# series = Librato::Metrics.get_series :requests, query
|
189
|
+
#
|
190
|
+
# @example Get series for metric grouped by tag and negated by tag filter
|
191
|
+
# query = { duration: 3600, resolution: 1, group_by: "environment", group_by_function: "sum", tags_search: "environment=!staging" }
|
192
|
+
# series = Librato::Metrics.get_series :requests, query
|
193
|
+
#
|
194
|
+
# @param [Symbol|String] metric_name Metric name
|
195
|
+
# @param [Hash] options Query options
|
196
|
+
def get_series(metric_name, options={})
|
197
|
+
raise ArgumentError, ":resolution and :duration or :start_time must be set" if options.empty?
|
198
|
+
query = options.dup
|
199
|
+
if query[:start_time].respond_to?(:year)
|
200
|
+
query[:start_time] = query[:start_time].to_i
|
201
|
+
end
|
202
|
+
if query[:end_time].respond_to?(:year)
|
203
|
+
query[:end_time] = query[:end_time].to_i
|
204
|
+
end
|
205
|
+
query[:resolution] ||= 1
|
206
|
+
unless query[:start_time] || query[:end_time]
|
207
|
+
query[:duration] ||= 3600
|
208
|
+
end
|
209
|
+
url = connection.build_url("measurements/#{metric_name}", query)
|
210
|
+
response = connection.get(url)
|
211
|
+
parsed = SmartJSON.read(response.body)
|
212
|
+
parsed["series"]
|
213
|
+
end
|
214
|
+
|
181
215
|
# Retrieve data points for a specific metric
|
182
216
|
#
|
183
217
|
# @example Get 20 most recent data points for metric
|
@@ -5,34 +5,25 @@ module Librato
|
|
5
5
|
class ExpectsStatus < Faraday::Response::Middleware
|
6
6
|
|
7
7
|
def on_complete(env)
|
8
|
-
|
8
|
+
# TODO: make exception output prettier
|
9
9
|
case env[:status]
|
10
10
|
when 401
|
11
|
-
raise Unauthorized.new(
|
11
|
+
raise Unauthorized.new(env.to_s, env)
|
12
12
|
when 403
|
13
|
-
raise Forbidden.new(
|
13
|
+
raise Forbidden.new(env.to_s, env)
|
14
14
|
when 404
|
15
|
-
raise NotFound.new(
|
15
|
+
raise NotFound.new(env.to_s, env)
|
16
16
|
when 422
|
17
|
-
raise EntityAlreadyExists.new(
|
17
|
+
raise EntityAlreadyExists.new(env.to_s, env)
|
18
18
|
when 400..499
|
19
|
-
raise ClientError.new(
|
19
|
+
raise ClientError.new(env.to_s, env)
|
20
20
|
when 500..599
|
21
|
-
raise ServerError.new(
|
21
|
+
raise ServerError.new(env.to_s, env)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
def sanitize_request(env)
|
26
|
-
{
|
27
|
-
status: env.status,
|
28
|
-
url: env.url.to_s,
|
29
|
-
user_agent: env.request_headers["User-Agent"],
|
30
|
-
request_body: env[:request_body],
|
31
|
-
response_headers: env.response_headers,
|
32
|
-
response_body: env.body
|
33
|
-
}
|
34
|
-
end
|
35
25
|
end
|
26
|
+
|
36
27
|
end
|
37
28
|
end
|
38
|
-
end
|
29
|
+
end
|
@@ -5,8 +5,6 @@ module Librato
|
|
5
5
|
module Metrics
|
6
6
|
module Persistence
|
7
7
|
class Direct
|
8
|
-
MEASUREMENT_TYPES = [:gauges, :counters]
|
9
|
-
|
10
8
|
# Persist the queued metrics directly to the
|
11
9
|
# Metrics web API.
|
12
10
|
#
|
@@ -18,9 +16,15 @@ module Librato
|
|
18
16
|
requests = [queued]
|
19
17
|
end
|
20
18
|
requests.each do |request|
|
19
|
+
resource =
|
20
|
+
if queued[:gauges] || queued[:counters]
|
21
|
+
"metrics"
|
22
|
+
else
|
23
|
+
"measurements"
|
24
|
+
end
|
21
25
|
payload = SmartJSON.write(request)
|
22
26
|
# expects 200
|
23
|
-
client.connection.post(
|
27
|
+
client.connection.post(resource, payload)
|
24
28
|
end
|
25
29
|
end
|
26
30
|
|
@@ -31,16 +35,16 @@ module Librato
|
|
31
35
|
reqs = []
|
32
36
|
# separate metric-containing values from global values
|
33
37
|
globals = fetch_globals(queued)
|
34
|
-
|
35
|
-
metrics = queued[
|
38
|
+
top_level_keys.each do |key|
|
39
|
+
metrics = queued[key]
|
36
40
|
next unless metrics
|
37
41
|
if metrics.size <= per_request
|
38
42
|
# we can fit all of this metric type in a single request
|
39
|
-
reqs << build_request(
|
43
|
+
reqs << build_request(key, metrics, globals)
|
40
44
|
else
|
41
45
|
# going to have to split things up
|
42
46
|
metrics.each_slice(per_request) do |elements|
|
43
|
-
reqs << build_request(
|
47
|
+
reqs << build_request(key, elements, globals)
|
44
48
|
end
|
45
49
|
end
|
46
50
|
end
|
@@ -51,8 +55,12 @@ module Librato
|
|
51
55
|
{type => metrics}.merge(globals)
|
52
56
|
end
|
53
57
|
|
58
|
+
def top_level_keys
|
59
|
+
[Librato::Metrics::PLURAL_TYPES, :measurements].flatten
|
60
|
+
end
|
61
|
+
|
54
62
|
def fetch_globals(queued)
|
55
|
-
queued.reject {|k, v|
|
63
|
+
queued.reject { |k, v| top_level_keys.include?(k) }
|
56
64
|
end
|
57
65
|
|
58
66
|
def queue_count(queued)
|
@@ -62,4 +70,4 @@ module Librato
|
|
62
70
|
end
|
63
71
|
end
|
64
72
|
end
|
65
|
-
end
|
73
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "set"
|
2
|
+
|
1
3
|
module Librato
|
2
4
|
module Metrics
|
3
5
|
|
@@ -7,7 +9,11 @@ module Librato
|
|
7
9
|
MEASUREMENTS_PER_REQUEST = 500
|
8
10
|
|
9
11
|
attr_reader :per_request, :last_submit_time
|
10
|
-
attr_accessor :prefix
|
12
|
+
attr_accessor :prefix, :tags
|
13
|
+
|
14
|
+
def tags
|
15
|
+
@tags ||= {}
|
16
|
+
end
|
11
17
|
|
12
18
|
# The current Client instance this queue is using to authenticate
|
13
19
|
# and connect to Librato Metrics. This will default to the primary
|
@@ -19,6 +25,11 @@ module Librato
|
|
19
25
|
@client ||= Librato::Metrics.client
|
20
26
|
end
|
21
27
|
|
28
|
+
def has_tags?
|
29
|
+
!@tags.empty?
|
30
|
+
end
|
31
|
+
alias :tags? :has_tags?
|
32
|
+
|
22
33
|
# The object this MetricSet will use to persist
|
23
34
|
#
|
24
35
|
def persister
|
@@ -82,11 +93,13 @@ module Librato
|
|
82
93
|
end
|
83
94
|
|
84
95
|
def setup_common_options(options)
|
96
|
+
validate_parameters(options)
|
85
97
|
@autosubmit_interval = options[:autosubmit_interval]
|
86
98
|
@client = options[:client] || Librato::Metrics.client
|
87
99
|
@per_request = options[:per_request] || MEASUREMENTS_PER_REQUEST
|
88
100
|
@source = options[:source]
|
89
|
-
@
|
101
|
+
@tags = options.fetch(:tags, {})
|
102
|
+
@time = (options[:time] && options[:time].to_i || options[:measure_time] && options[:measure_time].to_i)
|
90
103
|
@create_time = Time.now
|
91
104
|
@clear_on_failure = options[:clear_failures] || false
|
92
105
|
@prefix = options[:prefix]
|
@@ -99,6 +112,18 @@ module Librato
|
|
99
112
|
end
|
100
113
|
end
|
101
114
|
|
115
|
+
def validate_parameters(options)
|
116
|
+
invalid_combinations = [
|
117
|
+
[:source, :tags],
|
118
|
+
]
|
119
|
+
opts = options.keys.to_set
|
120
|
+
invalid_combinations.each do |combo|
|
121
|
+
if combo.to_set.subset?(opts)
|
122
|
+
raise InvalidParameters, "#{combo} cannot be simultaneously set"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
102
127
|
end
|
103
128
|
|
104
129
|
end
|
@@ -28,7 +28,9 @@ module Librato
|
|
28
28
|
# @return [Queue] returns self
|
29
29
|
def add(measurements)
|
30
30
|
measurements.each do |key, value|
|
31
|
+
multidimensional = has_tags?
|
31
32
|
if value.respond_to?(:each)
|
33
|
+
validate_parameters(value)
|
32
34
|
metric = value
|
33
35
|
metric[:name] = key.to_s
|
34
36
|
type = metric.delete(:type) || metric.delete('type') || 'gauge'
|
@@ -39,15 +41,24 @@ module Librato
|
|
39
41
|
if @prefix
|
40
42
|
metric[:name] = "#{@prefix}.#{metric[:name]}"
|
41
43
|
end
|
44
|
+
multidimensional = true if metric[:tags] || metric[:time]
|
42
45
|
type = ("#{type}s").to_sym
|
43
|
-
|
44
|
-
|
46
|
+
time_key = multidimensional ? :time : :measure_time
|
47
|
+
metric[:time] = metric.delete(:measure_time) if multidimensional && metric[:measure_time]
|
48
|
+
|
49
|
+
if metric[time_key]
|
50
|
+
metric[time_key] = metric[time_key].to_i
|
45
51
|
check_measure_time(metric)
|
46
52
|
elsif !skip_measurement_times
|
47
|
-
metric[
|
53
|
+
metric[time_key] = epoch_time
|
54
|
+
end
|
55
|
+
if multidimensional
|
56
|
+
@queued[:measurements] ||= []
|
57
|
+
@queued[:measurements] << metric
|
58
|
+
else
|
59
|
+
@queued[type] ||= []
|
60
|
+
@queued[type] << metric
|
48
61
|
end
|
49
|
-
@queued[type] ||= []
|
50
|
-
@queued[type] << metric
|
51
62
|
end
|
52
63
|
submit_check
|
53
64
|
self
|
@@ -81,6 +92,10 @@ module Librato
|
|
81
92
|
@queued[:gauges] || []
|
82
93
|
end
|
83
94
|
|
95
|
+
def measurements
|
96
|
+
@queued[:measurements] || []
|
97
|
+
end
|
98
|
+
|
84
99
|
# Combines queueable measures from the given object
|
85
100
|
# into this queue.
|
86
101
|
#
|
@@ -99,14 +114,24 @@ module Librato
|
|
99
114
|
end
|
100
115
|
Metrics::PLURAL_TYPES.each do |type|
|
101
116
|
if to_merge[type]
|
102
|
-
|
117
|
+
payload = reconcile(to_merge[type], to_merge[:source])
|
103
118
|
if @queued[type]
|
104
|
-
@queued[type] +=
|
119
|
+
@queued[type] += payload
|
105
120
|
else
|
106
|
-
@queued[type] =
|
121
|
+
@queued[type] = payload
|
107
122
|
end
|
108
123
|
end
|
109
124
|
end
|
125
|
+
|
126
|
+
if to_merge[:measurements]
|
127
|
+
payload = reconcile(to_merge[:measurements], to_merge[:tags])
|
128
|
+
if @queued[:measurements]
|
129
|
+
@queued[:measurements] += payload
|
130
|
+
else
|
131
|
+
@queued[:measurements] = payload
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
110
135
|
submit_check
|
111
136
|
self
|
112
137
|
end
|
@@ -117,8 +142,10 @@ module Librato
|
|
117
142
|
def queued
|
118
143
|
return {} if @queued.empty?
|
119
144
|
globals = {}
|
145
|
+
time = has_tags? ? :time : :measure_time
|
146
|
+
globals[time] = @time if @time
|
120
147
|
globals[:source] = @source if @source
|
121
|
-
globals[:
|
148
|
+
globals[:tags] = @tags if has_tags?
|
122
149
|
@queued.merge(globals)
|
123
150
|
end
|
124
151
|
|
@@ -133,16 +160,19 @@ module Librato
|
|
133
160
|
private
|
134
161
|
|
135
162
|
def check_measure_time(data)
|
136
|
-
|
163
|
+
time_keys = [:measure_time, :time]
|
164
|
+
|
165
|
+
if time_keys.any? { |key| data[key] && data[key] < Metrics::MIN_MEASURE_TIME }
|
137
166
|
raise InvalidMeasureTime, "Measure time for submitted metric (#{data}) is invalid."
|
138
167
|
end
|
139
168
|
end
|
140
169
|
|
141
|
-
def
|
142
|
-
|
170
|
+
def reconcile(measurements, val)
|
171
|
+
arr = val.is_a?(Hash) ? [@tags, :tags] : [@source, :source]
|
172
|
+
return measurements if !val || val == arr.first
|
143
173
|
measurements.map! do |measurement|
|
144
|
-
unless measurement[
|
145
|
-
measurement[
|
174
|
+
unless measurement[arr.last]
|
175
|
+
measurement[arr.last] = val
|
146
176
|
end
|
147
177
|
measurement
|
148
178
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Librato
|
2
|
+
module Metrics
|
3
|
+
|
4
|
+
class Util
|
5
|
+
SEPARATOR = "%%"
|
6
|
+
|
7
|
+
# Builds a Hash key from metric name and tags.
|
8
|
+
#
|
9
|
+
# @param metric_name [String] The unique identifying metric name of the property being tracked.
|
10
|
+
# @param tags [Hash] A set of name=value tag pairs that describe the particular data stream.
|
11
|
+
# @return [String] the Hash key
|
12
|
+
def self.build_key_for(metric_name, tags)
|
13
|
+
key_name = metric_name
|
14
|
+
tags.sort.each do |key, value|
|
15
|
+
k = key.to_s.downcase
|
16
|
+
v = value.is_a?(String) ? value.downcase : value
|
17
|
+
key_name = "#{key_name}#{SEPARATOR}#{k}=#{v}"
|
18
|
+
end
|
19
|
+
key_name
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -5,7 +5,9 @@ module Librato
|
|
5
5
|
|
6
6
|
describe Queue do
|
7
7
|
before(:all) { prep_integration_tests }
|
8
|
-
before(:each)
|
8
|
+
before(:each) do
|
9
|
+
delete_all_metrics
|
10
|
+
end
|
9
11
|
|
10
12
|
context "with a large number of metrics" do
|
11
13
|
it "submits them in multiple requests" do
|
@@ -70,6 +72,24 @@ module Librato
|
|
70
72
|
expect(bar['barsource'][0]['value']).to eq(456)
|
71
73
|
end
|
72
74
|
|
75
|
+
context "with tags" do
|
76
|
+
let(:queue) { Queue.new(tags: { hostname: "metrics-web-stg-1" }) }
|
77
|
+
|
78
|
+
it "respects default and individual tags" do
|
79
|
+
queue.add test_1: 123
|
80
|
+
queue.add test_2: { value: 456, tags: { hostname: "metrics-web-stg-2" }}
|
81
|
+
queue.submit
|
82
|
+
|
83
|
+
test_1 = Librato::Metrics.get_series :test_1, resolution: 1, duration: 3600
|
84
|
+
expect(test_1[0]["tags"]["hostname"]).to eq("metrics-web-stg-1")
|
85
|
+
expect(test_1[0]["measurements"][0]["value"]).to eq(123)
|
86
|
+
|
87
|
+
test_2 = Librato::Metrics.get_series :test_2, resolution: 1, duration: 3600
|
88
|
+
expect(test_2[0]["tags"]["hostname"]).to eq("metrics-web-stg-2")
|
89
|
+
expect(test_2[0]["measurements"][0]["value"]).to eq(456)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
73
93
|
end
|
74
94
|
|
75
95
|
end
|
@@ -360,6 +360,17 @@ module Librato
|
|
360
360
|
|
361
361
|
end
|
362
362
|
|
363
|
+
describe "#get_series" do
|
364
|
+
before { Metrics.submit test_series: { value: 123, tags: { hostname: "metrics-web-stg-1" } } }
|
365
|
+
|
366
|
+
it "gets series" do
|
367
|
+
series = Metrics.get_series :test_series, resolution: 1, duration: 3600
|
368
|
+
|
369
|
+
expect(series[0]["tags"]["hostname"]).to eq("metrics-web-stg-1")
|
370
|
+
expect(series[0]["measurements"][0]["value"]).to eq(123)
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
363
374
|
# Note: These are challenging to test end-to-end, should probably
|
364
375
|
# unit test instead. Disabling for now.
|
365
376
|
#
|
@@ -38,6 +38,69 @@ module Librato
|
|
38
38
|
expect(a.source).to be_nil
|
39
39
|
end
|
40
40
|
end
|
41
|
+
|
42
|
+
context "with valid arguments" do
|
43
|
+
it "initializes Aggregator" do
|
44
|
+
expect { Aggregator.new }.not_to raise_error
|
45
|
+
expect { Aggregator.new(source: "metrics-web-stg-1") }.not_to raise_error
|
46
|
+
expect { Aggregator.new(tags: { hostname: "metrics-web-stg-1" }) }.not_to raise_error
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "with invalid arguments" do
|
51
|
+
it "raises exception" do
|
52
|
+
expect {
|
53
|
+
Aggregator.new(
|
54
|
+
source: "metrics-web-stg-1",
|
55
|
+
tags: { hostname: "metrics-web-stg-1" }
|
56
|
+
)
|
57
|
+
}.to raise_error(InvalidParameters)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#tags" do
|
63
|
+
context "when set" do
|
64
|
+
let(:aggregator) { Aggregator.new(tags: { instance_id: "i-1234567a" }) }
|
65
|
+
it "gets @tags" do
|
66
|
+
expect(aggregator.tags).to be_a(Hash)
|
67
|
+
expect(aggregator.tags.keys).to include(:instance_id)
|
68
|
+
expect(aggregator.tags[:instance_id]).to eq("i-1234567a")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "when not set" do
|
73
|
+
let(:aggregator) { Aggregator.new }
|
74
|
+
it "defaults to empty hash" do
|
75
|
+
expect(aggregator.tags).to be_a(Hash)
|
76
|
+
expect(aggregator.tags).to be_empty
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "#tags=" do
|
82
|
+
it "sets @tags" do
|
83
|
+
expected_tags = { instance_id: "i-1234567b" }
|
84
|
+
expect{subject.tags = expected_tags}.to change{subject.tags}.from({}).to(expected_tags)
|
85
|
+
expect(subject.tags).to be_a(Hash)
|
86
|
+
expect(subject.tags).to eq(expected_tags)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "#has_tags?" do
|
91
|
+
context "when tags are set" do
|
92
|
+
it "returns true" do
|
93
|
+
subject.tags = { instance_id: "i-1234567f" }
|
94
|
+
|
95
|
+
expect(subject.has_tags?).to eq(true)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "when tags are not set" do
|
100
|
+
it "returns false" do
|
101
|
+
expect(subject.has_tags?).to eq(false)
|
102
|
+
end
|
103
|
+
end
|
41
104
|
end
|
42
105
|
|
43
106
|
describe "#add" do
|
@@ -45,6 +108,14 @@ module Librato
|
|
45
108
|
expect(subject.add(foo: 1234)).to eq(subject)
|
46
109
|
end
|
47
110
|
|
111
|
+
context "with invalid arguments" do
|
112
|
+
it "raises exception" do
|
113
|
+
expect {
|
114
|
+
subject.add test: { source: "metrics-web-stg-1", tags: { hostname: "metrics-web-stg-1" }, value: 123 }
|
115
|
+
}.to raise_error(InvalidParameters)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
48
119
|
context "with single hash argument" do
|
49
120
|
it "records a single aggregate" do
|
50
121
|
subject.add foo: 3000
|
@@ -91,6 +162,21 @@ module Librato
|
|
91
162
|
expect(subject.queued).to equal_unordered(expected)
|
92
163
|
end
|
93
164
|
|
165
|
+
context "when per-measurement tags" do
|
166
|
+
it "maintains specified tags" do
|
167
|
+
subject.add test: { tags: { hostname: "metrics-web-stg-1" }, value: 1 }
|
168
|
+
subject.add test: 5
|
169
|
+
subject.add test: { tags: { hostname: "metrics-web-stg-1" }, value: 6 }
|
170
|
+
subject.add test: 10
|
171
|
+
expected = [
|
172
|
+
{ name: "test", tags: { hostname: "metrics-web-stg-1" }, count: 2, sum: 7.0, min: 1.0, max: 6.0 },
|
173
|
+
{ name: "test", count: 2, sum: 15.0, min: 5.0, max: 10.0 }
|
174
|
+
]
|
175
|
+
|
176
|
+
expect(subject.queued[:measurements]).to equal_unordered(expected)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
94
180
|
context "with a prefix set" do
|
95
181
|
it "auto-prepends names" do
|
96
182
|
subject = Aggregator.new(prefix: 'foo')
|
@@ -160,6 +246,63 @@ module Librato
|
|
160
246
|
expect(subject.queued).to equal_unordered(expected)
|
161
247
|
end
|
162
248
|
end
|
249
|
+
|
250
|
+
context "with tags" do
|
251
|
+
context "when Aggregator is initialized with tags" do
|
252
|
+
let(:aggregator) { Aggregator.new(tags: { region: "us-east-1" }) }
|
253
|
+
|
254
|
+
it "applies top-level tags" do
|
255
|
+
expected = { name: "test", count: 2, sum: 3, min: 1, max: 2 }
|
256
|
+
aggregator.add test: 1
|
257
|
+
aggregator.add test: 2
|
258
|
+
|
259
|
+
expect(aggregator.queued[:tags]).to eq({ region: "us-east-1" })
|
260
|
+
expect(aggregator.queued[:measurements].first).to eq(expected)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
context "when tags are used as arguments" do
|
265
|
+
let(:aggregator) { Aggregator.new }
|
266
|
+
|
267
|
+
it "applies per-measurement tags" do
|
268
|
+
expected = { name: "test", count: 2, sum: 3, min: 1, max: 2, tags: { hostname: "metrics-web-stg-1" } }
|
269
|
+
aggregator.add test: { value: 1, tags: { hostname: "metrics-web-stg-1" } }
|
270
|
+
aggregator.add test: { value: 2, tags: { hostname: "metrics-web-stg-1" } }
|
271
|
+
|
272
|
+
expect(aggregator.queued[:tags]).to be_nil
|
273
|
+
expect(aggregator.queued[:measurements].first).to eq(expected)
|
274
|
+
end
|
275
|
+
|
276
|
+
context "when tags arguments are not sorted" do
|
277
|
+
let(:aggregator) { Aggregator.new }
|
278
|
+
|
279
|
+
it "uses sorted tags hash key" do
|
280
|
+
expected = { name: "test", count: 2, sum: 3, min: 1, max: 2, tags: { a: 1, b: 2, c: 3 } }
|
281
|
+
aggregator.add test: { value: 1, tags: { c: 3, b: 2, a: 1 } }
|
282
|
+
aggregator.add test: { value: 2, tags: { b: 2, a: 1, c: 3 } }
|
283
|
+
|
284
|
+
expect(aggregator.queued[:tags]).to be_nil
|
285
|
+
expect(aggregator.queued[:measurements].first).to eq(expected)
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
context "when Aggregator is initialized with tags and when tags are used as arguments" do
|
291
|
+
let(:aggregator) { Aggregator.new(tags: { region: "us-east-1" }) }
|
292
|
+
|
293
|
+
it "applies top-level tags and per-measurement tags" do
|
294
|
+
expected = { name: "test", count: 3, sum: 12, min: 3, max: 5, tags: { hostname: "metrics-web-stg-1" } }
|
295
|
+
aggregator.add test: { value: 3, tags: { hostname: "metrics-web-stg-1" } }
|
296
|
+
aggregator.add test: { value: 4, tags: { hostname: "metrics-web-stg-1" } }
|
297
|
+
aggregator.add test: { value: 5, tags: { hostname: "metrics-web-stg-1" } }
|
298
|
+
aggregator.add test: { value: 1, tags: { hostname: "metrics-web-stg-2" } }
|
299
|
+
aggregator.add test: { value: 2, tags: { region: "us-tirefire-1" } }
|
300
|
+
|
301
|
+
expect(aggregator.queued[:tags]).to eq({ region: "us-east-1" })
|
302
|
+
expect(aggregator.queued[:measurements].first).to eq(expected)
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
163
306
|
end
|
164
307
|
|
165
308
|
describe "#queued" do
|
@@ -171,10 +314,30 @@ module Librato
|
|
171
314
|
|
172
315
|
it "includes global measure_time if set" do
|
173
316
|
measure_time = (Time.now-1000).to_i
|
174
|
-
a = Aggregator.new(measure_time: measure_time)
|
317
|
+
a = Aggregator.new(source: "foo", measure_time: measure_time)
|
175
318
|
a.add foo: 12
|
176
319
|
expect(a.queued[:measure_time]).to eq(measure_time)
|
177
320
|
end
|
321
|
+
|
322
|
+
context "when tags are set" do
|
323
|
+
it "includes global tags" do
|
324
|
+
expected_tags = { region: "us-east-1" }
|
325
|
+
subject = Aggregator.new(tags: expected_tags)
|
326
|
+
subject.add test: 5
|
327
|
+
|
328
|
+
expect(subject.queued[:tags]).to eq(expected_tags)
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
context "when time is set" do
|
333
|
+
it "includes global time" do
|
334
|
+
expected_time = (Time.now-1000).to_i
|
335
|
+
subject = Aggregator.new(tags: { foo: "bar" }, time: expected_time)
|
336
|
+
subject.add test: 10
|
337
|
+
|
338
|
+
expect(subject.queued[:time]).to eq(expected_time)
|
339
|
+
end
|
340
|
+
end
|
178
341
|
end
|
179
342
|
|
180
343
|
describe "#submit" do
|
@@ -5,16 +5,22 @@ module Librato
|
|
5
5
|
|
6
6
|
describe Queue do
|
7
7
|
|
8
|
-
before(:
|
8
|
+
before(:all) do
|
9
9
|
@time = (Time.now.to_i - 1*60)
|
10
10
|
allow_any_instance_of(Queue).to receive(:epoch_time).and_return(@time)
|
11
11
|
end
|
12
12
|
|
13
13
|
describe "initialization" do
|
14
14
|
context "with specified client" do
|
15
|
+
let(:barney) { Client }
|
16
|
+
let(:queue) { Queue.new(client: barney) }
|
17
|
+
before do
|
18
|
+
allow(barney).to receive(:has_tags?).and_return(false)
|
19
|
+
allow(barney).to receive(:tags).and_return({})
|
20
|
+
allow(barney).to receive(:add_tags).and_return({})
|
21
|
+
end
|
22
|
+
|
15
23
|
it "sets to client" do
|
16
|
-
barney = Client
|
17
|
-
queue = Queue.new(client: barney)
|
18
24
|
expect(queue.client).to eq(barney)
|
19
25
|
end
|
20
26
|
end
|
@@ -25,6 +31,69 @@ module Librato
|
|
25
31
|
expect(queue.client).to eq(Librato::Metrics.client)
|
26
32
|
end
|
27
33
|
end
|
34
|
+
|
35
|
+
context "with valid arguments" do
|
36
|
+
it "initializes Queue" do
|
37
|
+
expect { Queue.new }.not_to raise_error
|
38
|
+
expect { Queue.new(source: "metrics-web-stg-1") }.not_to raise_error
|
39
|
+
expect { Queue.new(tags: { hostname: "metrics-web-stg-1" }) }.not_to raise_error
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "with invalid arguments" do
|
44
|
+
it "raises exception" do
|
45
|
+
expect {
|
46
|
+
Queue.new(
|
47
|
+
source: "metrics-web-stg-1",
|
48
|
+
tags: { hostname: "metrics-web-stg-1" }
|
49
|
+
)
|
50
|
+
}.to raise_error(InvalidParameters)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#tags" do
|
56
|
+
context "when set" do
|
57
|
+
let(:queue) { Queue.new(tags: { instance_id: "i-1234567a" }) }
|
58
|
+
it "gets @tags" do
|
59
|
+
expect(queue.tags).to be_a(Hash)
|
60
|
+
expect(queue.tags.keys).to include(:instance_id)
|
61
|
+
expect(queue.tags[:instance_id]).to eq("i-1234567a")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "when not set" do
|
66
|
+
let(:queue) { Queue.new }
|
67
|
+
it "defaults to empty hash" do
|
68
|
+
expect(queue.tags).to be_a(Hash)
|
69
|
+
expect(queue.tags).to be_empty
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "#tags=" do
|
75
|
+
it "sets @tags" do
|
76
|
+
expected_tags = { instance_id: "i-1234567b" }
|
77
|
+
expect{subject.tags = expected_tags}.to change{subject.tags}.from({}).to(expected_tags)
|
78
|
+
expect(subject.tags).to be_a(Hash)
|
79
|
+
expect(subject.tags).to eq(expected_tags)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "#has_tags?" do
|
84
|
+
context "when tags are set" do
|
85
|
+
it "returns true" do
|
86
|
+
subject.tags = { instance_id: "i-1234567f" }
|
87
|
+
|
88
|
+
expect(subject.has_tags?).to eq(true)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context "when tags are not set" do
|
93
|
+
it "returns false" do
|
94
|
+
expect(subject.has_tags?).to eq(false)
|
95
|
+
end
|
96
|
+
end
|
28
97
|
end
|
29
98
|
|
30
99
|
describe "#add" do
|
@@ -32,6 +101,14 @@ module Librato
|
|
32
101
|
expect(subject.add(foo: 123)).to eq(subject)
|
33
102
|
end
|
34
103
|
|
104
|
+
context "with invalid arguments" do
|
105
|
+
it "raises exception" do
|
106
|
+
expect {
|
107
|
+
subject.add test: { source: "metrics-web-stg-1", tags: { hostname: "metrics-web-stg-1" }, value: 123 }
|
108
|
+
}.to raise_error(InvalidParameters)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
35
112
|
context "with single hash argument" do
|
36
113
|
it "records a key-value gauge" do
|
37
114
|
expected = {gauges: [{name: 'foo', value: 3000, measure_time: @time}]}
|
@@ -137,6 +214,70 @@ module Librato
|
|
137
214
|
}.to raise_error(InvalidMeasureTime)
|
138
215
|
end
|
139
216
|
end
|
217
|
+
|
218
|
+
context "with tags" do
|
219
|
+
context "when Queue is initialized with tags" do
|
220
|
+
let(:queue) { Queue.new(tags: { region: "us-east-1" }) }
|
221
|
+
|
222
|
+
it "applies top-level tags" do
|
223
|
+
expected = { name: "test", value: 1, time: @time }
|
224
|
+
queue.add test: 1
|
225
|
+
|
226
|
+
expect(queue.queued[:tags]).to eq({ region: "us-east-1" })
|
227
|
+
expect(queue.queued[:measurements].first).to eq(expected)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
context "when tags are used as arguments" do
|
232
|
+
let(:queue) { Queue.new }
|
233
|
+
|
234
|
+
it "applies per-measurement tags" do
|
235
|
+
expected = { name: "test", value: 2, tags: { hostname: "metrics-web-stg-1" }, time: @time }
|
236
|
+
queue.add test: { value: 2, tags: { hostname: "metrics-web-stg-1" } }
|
237
|
+
|
238
|
+
expect(queue.queued[:tags]).to be_nil
|
239
|
+
expect(queue.queued[:measurements].first).to eq(expected)
|
240
|
+
end
|
241
|
+
|
242
|
+
it "converts legacy measure_time to time" do
|
243
|
+
expected_time = Time.now.to_i
|
244
|
+
expected_tags = { foo: "bar" }
|
245
|
+
expected = {
|
246
|
+
measurements: [{
|
247
|
+
name: "test", value: 1, tags: expected_tags, time: expected_time
|
248
|
+
}]
|
249
|
+
}
|
250
|
+
|
251
|
+
subject.add test: { value: 1, tags: expected_tags, measure_time: expected_time }
|
252
|
+
|
253
|
+
expect(subject.queued).to equal_unordered(expected)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
context "when Queue is initialized with tags and when tags are used as arguments" do
|
258
|
+
let(:queue) { Queue.new(tags: { region: "us-east-1" }) }
|
259
|
+
|
260
|
+
it "applies top-level tags and per-measurement tags" do
|
261
|
+
expected = { name: "test", value: 3, tags: { hostname: "metrics-web-stg-1" }, time: @time }
|
262
|
+
queue.add test: { value: 3, tags: { hostname: "metrics-web-stg-1" } }
|
263
|
+
|
264
|
+
expect(queue.queued[:tags]).to eq({ region: "us-east-1" })
|
265
|
+
expect(queue.queued[:measurements].first).to eq(expected)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
describe "#measurements" do
|
272
|
+
it "returns currently queued measurements" do
|
273
|
+
subject.add test_1: { tags: { region: "us-east-1" }, value: 1 },
|
274
|
+
test_2: { type: :counter, value: 2 }
|
275
|
+
expect(subject.measurements).to eq([{ name: "test_1", value: 1, tags: { region: "us-east-1" }, time: @time }])
|
276
|
+
end
|
277
|
+
|
278
|
+
it "returns [] when no queued measurements" do
|
279
|
+
expect(subject.measurements).to be_empty
|
280
|
+
end
|
140
281
|
end
|
141
282
|
|
142
283
|
describe "#counters" do
|
@@ -219,6 +360,39 @@ module Librato
|
|
219
360
|
expect(q2.queued).to equal_unordered(expected)
|
220
361
|
end
|
221
362
|
|
363
|
+
context "with tags" do
|
364
|
+
it "maintains specified tags" do
|
365
|
+
q1 = Queue.new
|
366
|
+
q1.add test: { tags: { hostname: "metrics-web-stg-1" }, value: 123 }
|
367
|
+
q2 = Queue.new(tags: { hostname: "metrics-web-stg-2" })
|
368
|
+
q2.merge!(q1)
|
369
|
+
|
370
|
+
expect(q2.queued[:measurements].first[:tags][:hostname]).to eq("metrics-web-stg-1")
|
371
|
+
end
|
372
|
+
|
373
|
+
it "does not change top-level tags" do
|
374
|
+
q1 = Queue.new(tags: { hostname: "metrics-web-stg-1" })
|
375
|
+
q1.add test: 456
|
376
|
+
q2 = Queue.new(tags: { hostname: "metrics-web-stg-2" })
|
377
|
+
q2.merge!(q1)
|
378
|
+
|
379
|
+
expect(q2.queued[:tags][:hostname]).to eq("metrics-web-stg-2")
|
380
|
+
end
|
381
|
+
|
382
|
+
it "tracks previous default tags" do
|
383
|
+
q1 = Queue.new(tags: { instance_id: "i-1234567a" })
|
384
|
+
q1.add test_1: 123
|
385
|
+
q2 = Queue.new(tags: { instance_type: "m3.medium" })
|
386
|
+
q2.add test_2: 456
|
387
|
+
q2.merge!(q1)
|
388
|
+
metric = q2.measurements.find { |measurement| measurement[:name] == "test_1" }
|
389
|
+
|
390
|
+
expect(metric[:tags][:instance_id]).to eq("i-1234567a")
|
391
|
+
expect(q2.queued[:tags]).to eq({ instance_type: "m3.medium" })
|
392
|
+
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
222
396
|
it "maintains specified sources" do
|
223
397
|
q1 = Queue.new
|
224
398
|
q1.add neo: {source: 'matrix', value: 123}
|
@@ -247,6 +421,7 @@ module Librato
|
|
247
421
|
end
|
248
422
|
end
|
249
423
|
end
|
424
|
+
end
|
250
425
|
|
251
426
|
it "handles empty cases" do
|
252
427
|
q1 = Queue.new
|
@@ -257,7 +432,6 @@ module Librato
|
|
257
432
|
gauges: [{name:"foo", value:123, measure_time: @time}]}
|
258
433
|
expect(q2.queued).to eq(expected)
|
259
434
|
end
|
260
|
-
end
|
261
435
|
|
262
436
|
context "with an aggregator" do
|
263
437
|
it "merges" do
|
@@ -301,10 +475,29 @@ module Librato
|
|
301
475
|
|
302
476
|
it "includes global measure_time if set" do
|
303
477
|
measure_time = (Time.now-1000).to_i
|
304
|
-
q = Queue.new(measure_time: measure_time)
|
478
|
+
q = Queue.new(source: "foo", measure_time: measure_time)
|
305
479
|
q.add foo: 12
|
306
480
|
expect(q.queued[:measure_time]).to eq(measure_time)
|
307
481
|
end
|
482
|
+
|
483
|
+
context "when tags are set" do
|
484
|
+
it "includes global tags" do
|
485
|
+
expected_tags = { region: "us-east-1" }
|
486
|
+
queue = Queue.new(tags: expected_tags)
|
487
|
+
queue.add test: 5
|
488
|
+
expect(queue.queued[:tags]).to eq(expected_tags)
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
492
|
+
context "when time is set" do
|
493
|
+
it "includes global time" do
|
494
|
+
expected_time = (Time.now-1000).to_i
|
495
|
+
queue = Queue.new(tags: { foo: "bar" }, time: expected_time)
|
496
|
+
queue.add test: 10
|
497
|
+
expect(queue.queued[:time]).to eq(expected_time)
|
498
|
+
end
|
499
|
+
end
|
500
|
+
|
308
501
|
end
|
309
502
|
|
310
503
|
describe "#size" do
|
@@ -318,6 +511,15 @@ module Librato
|
|
318
511
|
register_cents: {type: :gauge, value: 211101}
|
319
512
|
expect(subject.size).to eq(4)
|
320
513
|
end
|
514
|
+
|
515
|
+
context "when measurement present" do
|
516
|
+
it "returns count of measurements" do
|
517
|
+
subject.add test_1: { tags: { hostname: "metrics-web-stg-1" }, value: 1 },
|
518
|
+
test_2: { tags: { hostname: "metrics-web-stg-2" }, value: 2}
|
519
|
+
|
520
|
+
expect(subject.size).to eq(2)
|
521
|
+
end
|
522
|
+
end
|
321
523
|
end
|
322
524
|
|
323
525
|
describe "#submit" do
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Librato
|
4
|
+
module Metrics
|
5
|
+
|
6
|
+
describe Util do
|
7
|
+
|
8
|
+
describe "#build_key_for" do
|
9
|
+
it "builds a Hash key" do
|
10
|
+
metric_name = "requests"
|
11
|
+
tags = { status: 200, MeThoD: "GET", controller: "users", ACTION: "show" }
|
12
|
+
expected = "requests%%action=show%%method=get%%controller=users%%status=200"
|
13
|
+
actual = Util.build_key_for(metric_name, tags)
|
14
|
+
|
15
|
+
expect(expected).to eq(actual)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: librato-metrics
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
5
|
-
prerelease:
|
4
|
+
version: 2.1.0.beta
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Matt Sanders
|
@@ -36,7 +36,7 @@ cert_chain:
|
|
36
36
|
dzJsaG9DTUxDU1NqOVQvWXlSVEwzVVFZb0s1cFBBNzYKaHZqeDBXSlA4cHpa
|
37
37
|
TUpQS0pCUlpRWEpPNWlmRVB5S2paeU1pNVhNSG1ydERjbEhMajNzeDRSQXZF
|
38
38
|
WmpHV2tSUApKU1E9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
|
39
|
-
date: 2016-11-
|
39
|
+
date: 2016-11-04 00:00:00.000000000 Z
|
40
40
|
dependencies:
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: faraday
|
@@ -106,6 +106,7 @@ files:
|
|
106
106
|
- lib/librato/metrics/processor.rb
|
107
107
|
- lib/librato/metrics/queue.rb
|
108
108
|
- lib/librato/metrics/smart_json.rb
|
109
|
+
- lib/librato/metrics/util.rb
|
109
110
|
- lib/librato/metrics/version.rb
|
110
111
|
- librato-metrics.gemspec
|
111
112
|
- spec/integration/metrics/annotator_spec.rb
|
@@ -121,6 +122,7 @@ files:
|
|
121
122
|
- spec/unit/metrics/queue/autosubmission_spec.rb
|
122
123
|
- spec/unit/metrics/queue_spec.rb
|
123
124
|
- spec/unit/metrics/smart_json_spec.rb
|
125
|
+
- spec/unit/metrics/util_spec.rb
|
124
126
|
- spec/unit/metrics_spec.rb
|
125
127
|
homepage: https://github.com/librato/librato-metrics
|
126
128
|
licenses:
|
@@ -139,9 +141,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
139
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
142
|
none: false
|
141
143
|
requirements:
|
142
|
-
- - ! '
|
144
|
+
- - ! '>'
|
143
145
|
- !ruby/object:Gem::Version
|
144
|
-
version:
|
146
|
+
version: 1.3.1
|
145
147
|
requirements: []
|
146
148
|
rubyforge_project:
|
147
149
|
rubygems_version: 1.8.23.2
|
@@ -162,5 +164,6 @@ test_files:
|
|
162
164
|
- spec/unit/metrics/queue/autosubmission_spec.rb
|
163
165
|
- spec/unit/metrics/queue_spec.rb
|
164
166
|
- spec/unit/metrics/smart_json_spec.rb
|
167
|
+
- spec/unit/metrics/util_spec.rb
|
165
168
|
- spec/unit/metrics_spec.rb
|
166
169
|
has_rdoc:
|
metadata.gz.sig
CHANGED
@@ -1,3 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
��R�!�aBl�|6��ҳt���Ư�R6�0`7�CZ�*�wjq���/G�a�&e�D3�I��
|
1
|
+
��ZWn�V��K䓨%U
|
2
|
+
�3��,/���������y�����r�C�U��y�$���:�6���O0��3�0��Ip
|