Skip to content

Commit 55cb30a

Browse files
committed
feat: Configure metric metadata upon startup
1 parent eaa4d29 commit 55cb30a

File tree

3 files changed

+178
-18
lines changed

3 files changed

+178
-18
lines changed

lambda_function.rb

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,23 @@ def lambda_handler(event: {}, context: {})
2828
@event = event
2929
log_context
3030

31-
@slowlog_check ||= SlowlogCheck.new(
32-
ddog: Dogapi::Client.new(
33-
ENV.fetch('DATADOG_API_KEY'),
34-
ENV.fetch('DATADOG_APP_KEY')
35-
),
36-
redis: Redis.new(
37-
host: ENV.fetch('REDIS_HOST'),
38-
ssl: :true
39-
),
40-
namespace: ENV.fetch('NAMESPACE'),
41-
env: ENV.fetch('ENV'),
42-
metricname: 'scribddev.redis.slowlog.micros'
43-
)
31+
unless defined? @slowlog_check
32+
@slowlog_check = SlowlogCheck.new(
33+
ddog: Dogapi::Client.new(
34+
ENV.fetch('DATADOG_API_KEY'),
35+
ENV.fetch('DATADOG_APP_KEY')
36+
),
37+
redis: Redis.new(
38+
host: ENV.fetch('REDIS_HOST'),
39+
ssl: :true
40+
),
41+
namespace: ENV.fetch('NAMESPACE'),
42+
env: ENV.fetch('ENV'),
43+
metricname: 'scribddev.redis.slowlog.micros'
44+
)
45+
46+
@slowlog_check.update_metadatas
47+
end
4448

4549
@slowlog_check.ship_slowlogs
4650

lib/slowlog_check.rb

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def last_datadog_metrics_submitted_by_me_in_the_last_day
3131
Time.now
3232
)
3333

34-
raise "Error getting last datadog metric submitted by me" unless resp[1].fetch("status") == "ok"
34+
raise "Error getting last datadog metric submitted by me" unless status_or_error(resp) == "ok"
3535
resp
3636
end
3737

@@ -172,7 +172,7 @@ def emit_point(params)
172172
host = params.fetch(:host, replication_group)
173173
tags = params.fetch(:tags, default_tags)
174174

175-
LOGGER.info "Sending slowlog entry: #{points.first[1]}µs executing #{tags[:command]} at #{points.first[0]}."
175+
LOGGER.info "Sending slowlog entry: #{metric}: #{points.first[1]}µs executing #{tags[:command]} at #{points.first[0]}."
176176
resp = @ddog.emit_points(
177177
metric,
178178
points,
@@ -183,8 +183,11 @@ def emit_point(params)
183183
tags: tags
184184
}
185185
)
186-
raise "Error submitting metric for #{replication_group}" unless resp[1].fetch("status") == "ok"
186+
raise "Error submitting metric for #{replication_group}" unless status_or_error(resp) == "ok"
187+
188+
# Sigh. After doing all the work to pass around Time objects, dogapi-rb changes this to an integer.
187189
@last_time_submitted = Time.at(points.first[0])
190+
LOGGER.info "#{metric} set #{status_or_error(resp)} at #{Time.at(points.first[0])}"
188191
resp
189192
end
190193

@@ -217,5 +220,74 @@ def ship_slowlogs
217220
end
218221
end
219222
end
220-
end
221223

224+
225+
def metric_metadatas
226+
[
227+
'avg',
228+
'median',
229+
'min',
230+
'max',
231+
'95percentile'
232+
].map { |metric|
233+
{
234+
"name" => @metricname + '.' + metric,
235+
"description" => "slowlog duration #{metric} (µs)",
236+
"short_name" => "#{metric} (µs)",
237+
"integration" => nil,
238+
"statsd_interval" => 60,
239+
"per_unit" => nil,
240+
"type" => "gauge",
241+
"unit" => "µs"
242+
}
243+
}.push(
244+
{
245+
"name" => @metricname + '.count',
246+
"type" => 'rate',
247+
"description" => 'slowlog entries per minute',
248+
"short_name" => 'per minute',
249+
"per_unit" => 'entry',
250+
"integration" => nil,
251+
"unit" => 'entries',
252+
"statsd_interval" => 60
253+
}
254+
)
255+
end
256+
257+
def get_metadatas
258+
[
259+
'avg',
260+
'median',
261+
'min',
262+
'max',
263+
'95percentile',
264+
'count'
265+
].map do |metric|
266+
name = @metricname + '.' + metric
267+
@ddog.get_metadata(name)[1]
268+
.merge("name" => name)
269+
end
270+
end
271+
272+
def diff_metadatas
273+
metric_metadatas - get_metadatas
274+
end
275+
276+
277+
def update_metadatas
278+
diff_metadatas.each do |metadata|
279+
name = metadata.delete("name")
280+
resp = @ddog.update_metadata(
281+
name,
282+
metadata.transform_keys { |key| key.to_sym rescue key }
283+
)
284+
LOGGER.info "Updating metadata for #{name} #{status_or_error(resp)}"
285+
end
286+
end
287+
288+
def status_or_error(resp)
289+
return resp[1].fetch("status") if resp[1].key?("status")
290+
return resp[1].fetch("errors") if resp[1].key?("errors")
291+
return resp
292+
end
293+
end

spec/slowlog_check_spec.rb

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,11 +221,12 @@
221221
end
222222

223223
describe '#ship_slowlogs' do
224+
subject { slowlog_check.ship_slowlogs }
224225
let(:tags) { slowlog_check.default_tags.merge(command: 'eval') }
225226

226227
it 'sends the right data to datadog' do
227228
allow(ddog).to receive(:emit_points) {["200", { "status" => "ok" }]}
228-
slowlog_check.ship_slowlogs
229+
subject
229230

230231
expect(ddog).to have_received(:emit_points).with(
231232
"rspec.redis.slowlog.micros.avg",
@@ -248,5 +249,88 @@
248249
end
249250
end
250251

252+
describe 'metadata' do
253+
before(:each) {
254+
allow(ddog).to receive(:get_metadata) { |name|
255+
metric = name.split('.').last
256+
["200",
257+
{
258+
"description"=>"slowlog duration #{metric} (µs)",
259+
"short_name"=>"#{metric} (µs)",
260+
"integration"=>nil,
261+
"statsd_interval"=>60,
262+
"per_unit"=>nil,
263+
"type"=>"gauge",
264+
"unit"=>"µs"
265+
}
266+
]
267+
}
268+
}
269+
270+
describe '#diff_metadatas' do
271+
subject { slowlog_check.diff_metadatas }
272+
273+
let(:diff) {
274+
{
275+
"name"=>"rspec.redis.slowlog.micros.count",
276+
"description"=>"slowlog entries per minute",
277+
"short_name"=>"per minute",
278+
"integration"=>nil,
279+
"statsd_interval"=>60,
280+
"per_unit"=>"entry",
281+
"type"=>"rate",
282+
"unit"=>"entries"
283+
}
284+
}
285+
286+
it { is_expected.to contain_exactly(diff) }
287+
end
288+
289+
describe '#update_metadatas' do
290+
subject { slowlog_check.update_metadatas }
291+
let(:diff) {
292+
{
293+
description: 'slowlog entries per minute',
294+
integration: nil,
295+
per_unit: 'entry',
296+
short_name: 'per minute',
297+
statsd_interval: 60,
298+
type: 'rate',
299+
unit: 'entries'
300+
}
301+
}
302+
it 'sends the right data to datadog' do
303+
allow(ddog).to receive(:update_metadata) {["200", {"status" => "ok"}]}
304+
subject
305+
306+
expect(ddog).to have_received(:update_metadata).with(
307+
'rspec.redis.slowlog.micros.count',
308+
diff
309+
)
251310

311+
end
312+
end
313+
end
314+
315+
describe '#status_or_error' do
316+
context 'ok' do
317+
subject { slowlog_check.status_or_error(["200", {"status" => "ok"}]) }
318+
319+
it { is_expected.to eq('ok') }
320+
321+
end
322+
323+
context 'error' do
324+
subject { slowlog_check.status_or_error(["404", {"errors" => ["error"]}]) }
325+
326+
it { is_expected.to eq(['error']) }
327+
end
328+
329+
context 'otherwise' do
330+
subject { slowlog_check.status_or_error(["404", {"somenewthing" => ["error"]}]) }
331+
332+
it { is_expected.to eq(["404", {"somenewthing" => ['error']}]) }
333+
end
334+
335+
end
252336
end

0 commit comments

Comments
 (0)