interferon 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a9fbb5fdb83e9978e96990983e1c815fd18e7cdc
4
- data.tar.gz: 0d5b080a2ad8dbdd8a16edd1bcae27aadfb6c366
3
+ metadata.gz: 1c7f74fc8e23da780fdf783cdb98387321d20513
4
+ data.tar.gz: 5aa81e287ab880c2d3e7af7bd96a035d41b3db21
5
5
  SHA512:
6
- metadata.gz: 542ec78306622d95e55f698f2c0b35b7f0a8365a8eb0f2f85d0faff851fd22f5ddaef5d5b5c2f8adf585f0a297d23f0684cf5293122073729bd326cd23dab530
7
- data.tar.gz: 271d43056cc9be797fb8e4ae3f98d4370518481f71bcf4b1f0d749b09e1433e36666b9ca701439d4bc6167a9857a2c53977836131d7f5a55355e44fa6d140c9d
6
+ metadata.gz: 82c25b9118d41092d6ab131dd7edba612f40e68d4959bd0849efb4d0d2483bd5056b806dfc1c6f7e21381badd83cfb1e4f4e62fba8497bb3e6c52c4f33479dd2
7
+ data.tar.gz: 24740188b929de430442f21501ef75de6a7fd148835c3491da1827c77f62b169c2ccca38507ee400f4c938d87ac273935ce63bb9c966c6da4851e6c49d0cc6c9
@@ -120,7 +120,7 @@ module Interferon
120
120
  end
121
121
 
122
122
  def audit(v = nil, &block)
123
- get_or_set(:@audit, v, block, true)
123
+ get_or_set(:@audit, v, block, false)
124
124
  end
125
125
  end
126
126
 
@@ -66,8 +66,8 @@ module Interferon::Destinations
66
66
  @api_errors ||= []
67
67
  end
68
68
 
69
- def generate_message(message, people)
70
- [message, ALERT_KEY, people.map { |p| "@#{p}" }].flatten.join("\n")
69
+ def self.generate_message(message, people)
70
+ [message, ALERT_KEY, people.sort.map { |p| "@#{p}" }].flatten.join("\n")
71
71
  end
72
72
 
73
73
  def fetch_existing_alerts
@@ -132,7 +132,7 @@ module Interferon::Destinations
132
132
  # create a message which includes the notifications
133
133
  # Datadog may have a race condition where alerts created in a bad state may be triggered
134
134
  # during the dry-run creation process. Delete people from dry-run alerts to avoid this
135
- message = generate_message(alert['message'], people)
135
+ message = self.class.generate_message(alert['message'], people)
136
136
 
137
137
  # create the hash of options to send to datadog
138
138
  alert_options = {
@@ -201,7 +201,7 @@ EOM
201
201
  alert['monitor_type'],
202
202
  datadog_query,
203
203
  name: alert['name'],
204
- message: @dry_run ? generate_message(alert, []) : message,
204
+ message: @dry_run ? self.class.generate_message(alert, []) : message,
205
205
  options: alert_options
206
206
  )
207
207
  end
@@ -234,10 +234,10 @@ EOM
234
234
  alert['monitor_type'],
235
235
  datadog_query,
236
236
  name: alert['name'],
237
- message: generate_message(alert, []),
237
+ message: self.class.generate_message(alert, []),
238
238
  options: alert_options
239
239
  )
240
- elsif alert['monitor_type'] == existing_alert['type']
240
+ elsif self.class.same_monitor_type(alert['monitor_type'], existing_alert['type'])
241
241
  resp = @dog.update_monitor(
242
242
  id,
243
243
  datadog_query,
@@ -290,6 +290,67 @@ EOM
290
290
  end
291
291
  end
292
292
 
293
+ def remove_alert_by_id(alert_id)
294
+ # This should only be used by dry-run to clean up created dry-run alerts
295
+ log.debug("deleting alert, id: #{alert_id}")
296
+ resp = @dog.delete_monitor(alert_id)
297
+ code = resp[0].to_i
298
+ log_datadog_response_code(resp, code, :deleting)
299
+ end
300
+
301
+ def need_update(alert_people_pair, existing_alerts_from_api)
302
+ alert, people = alert_people_pair
303
+ existing = existing_alerts_from_api[alert['name']]
304
+ existing.nil? || !self.class.same_alerts(alert, people, existing)
305
+ end
306
+
307
+ def self.normalize_monitor_type(monitor_type)
308
+ # Convert 'query alert' type to 'metric alert' type. They can used interchangeably when
309
+ # submitting monitors to Datadog. Datadog will automatically do the conversion to 'query
310
+ # alert' for a "complex" query that includes multiple metrics/tags while using 'metric alert'
311
+ # for monitors that include a single scope/metric.
312
+ monitor_type == 'query alert' ? 'metric alert' : monitor_type
313
+ end
314
+
315
+ def self.same_monitor_type(monitor_type_a, monitor_type_b)
316
+ normalize_monitor_type(monitor_type_a) == normalize_monitor_type(monitor_type_b)
317
+ end
318
+
319
+ def self.same_alerts(alert, people, alert_api_json)
320
+ prev_alert = {
321
+ monitor_type: normalize_monitor_type(alert_api_json['type']),
322
+ query: alert_api_json['query'].strip,
323
+ message: alert_api_json['message'].strip,
324
+ evaluation_delay: alert_api_json['options']['evaluation_delay'],
325
+ notify_no_data: alert_api_json['options']['notify_no_data'],
326
+ notify_audit: alert_api_json['options']['notify_audit'],
327
+ no_data_timeframe: alert_api_json['options']['no_data_timeframe'],
328
+ silenced: alert_api_json['options']['silenced'],
329
+ thresholds: alert_api_json['options']['thresholds'],
330
+ timeout_h: alert_api_json['options']['timeout_h'],
331
+ }
332
+
333
+ new_alert = {
334
+ monitor_type: normalize_monitor_type(alert['monitor_type']),
335
+ query: alert['metric']['datadog_query'],
336
+ message: generate_message(alert['message'], people).strip,
337
+ evaluation_delay: alert['evaluation_delay'],
338
+ notify_no_data: alert['notify_no_data'],
339
+ notify_audit: alert['notify']['audit'],
340
+ no_data_timeframe: alert['no_data_timeframe'],
341
+ silenced: alert['silenced'],
342
+ thresholds: alert['thresholds'],
343
+ timeout_h: alert['timeout_h'],
344
+ }
345
+
346
+ unless alert['require_full_window'].nil?
347
+ prev_alert[:require_full_window] = alert_api_json['options']['require_full_window']
348
+ new_alert[:require_full_window] = alert['require_full_window']
349
+ end
350
+
351
+ prev_alert == new_alert
352
+ end
353
+
293
354
  def report_stats
294
355
  @stats.each do |k, v|
295
356
  statsd.gauge("datadog.#{k}", v)
@@ -307,14 +368,6 @@ EOM
307
368
  )
308
369
  end
309
370
 
310
- def remove_alert_by_id(alert_id)
311
- # This should only be used by dry-run to clean up created dry-run alerts
312
- log.debug("deleting alert, id: #{alert_id}")
313
- resp = @dog.delete_monitor(alert_id)
314
- code = resp[0].to_i
315
- log_datadog_response_code(resp, code, :deleting)
316
- end
317
-
318
371
  def log_datadog_response_code(resp, code, action, alert = nil)
319
372
  # log whenever we've encountered errors
320
373
  if code != 200 && !alert.nil?
@@ -1,3 +1,3 @@
1
1
  module Interferon
2
- VERSION = '0.1.3'.freeze
2
+ VERSION = '0.1.4'.freeze
3
3
  end
data/lib/interferon.rb CHANGED
@@ -106,11 +106,11 @@ module Interferon
106
106
  people_count += people.count
107
107
  end
108
108
 
109
- log.info "read #{people_count} people in #{source_groups.count} groups" \
109
+ log.info "read #{people_count} people in #{source_groups.count} groups " \
110
110
  "from source #{source.class.name}"
111
111
  end
112
112
 
113
- log.info "total of #{groups.values.flatten.count} people in #{groups.count} groups" \
113
+ log.info "total of #{groups.values.flatten.count} people in #{groups.count} groups " \
114
114
  "from #{sources.count} sources"
115
115
 
116
116
  statsd.gauge('groups.sources', sources.count)
@@ -191,7 +191,7 @@ module Interferon
191
191
 
192
192
  alerts_queue = build_alerts_queue(hosts, alerts, groups)
193
193
  updates_queue = alerts_queue.reject do |_name, alert_people_pair|
194
- !Interferon.need_update(dest, alert_people_pair, existing_alerts)
194
+ !dest.need_update(alert_people_pair, existing_alerts)
195
195
  end
196
196
 
197
197
  # Add dry-run prefix to alerts and delete id to avoid impacting real alerts
@@ -205,7 +205,7 @@ module Interferon
205
205
 
206
206
  # Build new queue with dry-run prefixes and ensure they are silenced
207
207
  alerts_queue.each do |_name, alert_people_pair|
208
- alert = alert_people_pair[0]
208
+ alert, _people = alert_people_pair
209
209
  dry_run_alert_name = DRY_RUN_ALERTS_NAME_PREFIX + alert['name']
210
210
  alert.change_name(dry_run_alert_name)
211
211
  alert.silence
@@ -218,7 +218,7 @@ module Interferon
218
218
  # alerts that aren't being generated anymore
219
219
  to_remove = existing_alerts.dup
220
220
  alerts_queue.each do |_name, alert_people_pair|
221
- alert = alert_people_pair[0]
221
+ alert, _people = alert_people_pair
222
222
  old_alerts = to_remove[alert['name']]
223
223
 
224
224
  next if old_alerts.nil?
@@ -247,7 +247,7 @@ module Interferon
247
247
  def do_regular_update(dest, hosts, alerts, existing_alerts, groups)
248
248
  alerts_queue = build_alerts_queue(hosts, alerts, groups)
249
249
  updates_queue = alerts_queue.reject do |_name, alert_people_pair|
250
- !Interferon.need_update(dest, alert_people_pair, existing_alerts)
250
+ !dest.need_update(alert_people_pair, existing_alerts)
251
251
  end
252
252
 
253
253
  # Create alerts in destination
@@ -257,7 +257,7 @@ module Interferon
257
257
  # alerts that aren't being generated anymore
258
258
  to_remove = existing_alerts.dup
259
259
  alerts_queue.each do |_name, alert_people_pair|
260
- alert = alert_people_pair[0]
260
+ alert, _people = alert_people_pair
261
261
  old_alerts = to_remove[alert['name']]
262
262
 
263
263
  next if old_alerts.nil?
@@ -378,60 +378,5 @@ module Interferon
378
378
  end
379
379
  alerts_queue
380
380
  end
381
-
382
- def self.need_update(dest, alert_people_pair, existing_alerts_from_api)
383
- alert = alert_people_pair[0]
384
- existing = existing_alerts_from_api[alert['name']]
385
- if existing.nil?
386
- true
387
- else
388
- !same_alerts(dest, alert_people_pair, existing)
389
- end
390
- end
391
-
392
- def self.normalize_monitor_type(monitor_type)
393
- # Convert 'query alert' type to 'metric alert' type. They can used interchangeably when
394
- # submitting monitors to Datadog. Datadog will automatically do the conversion to 'query
395
- # alert' for a "complex" query that includes multiple metrics/tags while using 'metric alert'
396
- # for monitors that include a single scope/metric.
397
- monitor_type == 'query alert' ? 'metric alert' : monitor_type
398
- end
399
-
400
- def self.same_alerts(dest, alert_people_pair, alert_api_json)
401
- alert, people = alert_people_pair
402
-
403
- prev_alert = {
404
- monitor_type: normalize_monitor_type(alert_api_json['type']),
405
- query: alert_api_json['query'].strip,
406
- message: alert_api_json['message'].strip,
407
- evaluation_delay: alert_api_json['options']['evaluation_delay'],
408
- notify_no_data: alert_api_json['options']['notify_no_data'],
409
- notify_audit: alert_api_json['options']['notify_audit'],
410
- no_data_timeframe: alert_api_json['options']['no_data_timeframe'],
411
- silenced: alert_api_json['options']['silenced'],
412
- thresholds: alert_api_json['options']['thresholds'],
413
- timeout_h: alert_api_json['options']['timeout_h'],
414
- }
415
-
416
- new_alert = {
417
- monitor_type: normalize_monitor_type(alert['monitor_type']),
418
- query: alert['metric']['datadog_query'],
419
- message: dest.generate_message(alert['message'], people).strip,
420
- evaluation_delay: alert['evaluation_delay'],
421
- notify_no_data: alert['notify_no_data'],
422
- notify_audit: alert['notify']['audit'],
423
- no_data_timeframe: alert['no_data_timeframe'],
424
- silenced: alert['silenced'],
425
- thresholds: alert['thresholds'],
426
- timeout_h: alert['timeout_h'],
427
- }
428
-
429
- unless alert['require_full_window'].nil?
430
- prev_alert[:require_full_window] = alert_api_json['options']['require_full_window']
431
- new_alert[:require_full_window] = alert['require_full_window']
432
- end
433
-
434
- prev_alert == new_alert
435
- end
436
381
  end
437
382
  end
@@ -4,7 +4,7 @@ require 'interferon/destinations/datadog'
4
4
 
5
5
  include Interferon
6
6
 
7
- describe Interferon::Interferon do
7
+ describe Interferon::Destinations::Datadog do
8
8
  let(:the_existing_alerts) { mock_existing_alerts }
9
9
  let(:dest) { MockDest.new(the_existing_alerts) }
10
10
 
@@ -13,35 +13,35 @@ describe Interferon::Interferon do
13
13
  alert1 = create_test_alert('name1', 'testquery', 'message1')
14
14
  alert2 = mock_alert_json('name2', 'testquery', 'message2')
15
15
 
16
- expect(Interferon::Interferon.same_alerts(dest, [alert1, []], alert2)).to be false
16
+ expect(Interferon::Destinations::Datadog.same_alerts(alert1, [], alert2)).to be false
17
17
  end
18
18
 
19
19
  it 'detects a change if datadog query is different' do
20
20
  alert1 = create_test_alert('name1', 'testquery1', 'message1')
21
21
  alert2 = mock_alert_json('name2', 'testquery2', 'message2')
22
22
 
23
- expect(Interferon::Interferon.same_alerts(dest, [alert1, []], alert2)).to be false
23
+ expect(Interferon::Destinations::Datadog.same_alerts(alert1, [], alert2)).to be false
24
24
  end
25
25
 
26
26
  it 'detects a change if alert notify_no_data is different' do
27
27
  alert1 = create_test_alert('name1', 'testquery1', 'message1', notify_no_data: false)
28
28
  alert2 = mock_alert_json('name2', 'testquery2', 'message2', nil, [1], notify_no_data: true)
29
29
 
30
- expect(Interferon::Interferon.same_alerts(dest, [alert1, []], alert2)).to be false
30
+ expect(Interferon::Destinations::Datadog.same_alerts(alert1, [], alert2)).to be false
31
31
  end
32
32
 
33
33
  it 'detects a change if alert silenced is different' do
34
34
  alert1 = create_test_alert('name1', 'testquery1', 'message1', silenced: true)
35
35
  alert2 = mock_alert_json('name2', 'testquery2', 'message2', nil, [1], silenced: {})
36
36
 
37
- expect(Interferon::Interferon.same_alerts(dest, [alert1, []], alert2)).to be false
37
+ expect(Interferon::Destinations::Datadog.same_alerts(alert1, [], alert2)).to be false
38
38
  end
39
39
 
40
40
  it 'detects a change if alert no_data_timeframe is different' do
41
41
  alert1 = create_test_alert('name1', 'testquery1', 'message1', no_data_timeframe: nil)
42
42
  alert2 = mock_alert_json('name2', 'testquery2', 'message2', nil, [1], no_data_timeframe: 60)
43
43
 
44
- expect(Interferon::Interferon.same_alerts(dest, [alert1, []], alert2)).to be false
44
+ expect(Interferon::Destinations::Datadog.same_alerts(alert1, [], alert2)).to be false
45
45
  end
46
46
 
47
47
  it 'detects a change if alert require_full_window is different' do
@@ -50,14 +50,14 @@ describe Interferon::Interferon do
50
50
  'name2', 'testquery2', 'message2', nil, [1], require_full_window: true
51
51
  )
52
52
 
53
- expect(Interferon::Interferon.same_alerts(dest, [alert1, []], alert2)).to be false
53
+ expect(Interferon::Destinations::Datadog.same_alerts(alert1, [], alert2)).to be false
54
54
  end
55
55
 
56
56
  it 'detects a change if alert evaluation_delay is different' do
57
57
  alert1 = create_test_alert('name1', 'testquery1', 'message1', evaluation_delay: nil)
58
58
  alert2 = mock_alert_json('name2', 'testquery2', 'message2', nil, [1], evaluation_delay: 300)
59
59
 
60
- expect(Interferon::Interferon.same_alerts(dest, [alert1, []], alert2)).to be false
60
+ expect(Interferon::Destinations::Datadog.same_alerts(alert1, [], alert2)).to be false
61
61
  end
62
62
 
63
63
  it 'does not detect a change when alert datadog query and message are the same' do
@@ -66,7 +66,7 @@ describe Interferon::Interferon do
66
66
  'name1', 'testquery1', "message1\nThis alert was created via the alerts framework"
67
67
  )
68
68
 
69
- expect(Interferon::Interferon.same_alerts(dest, [alert1, []], alert2)).to be true
69
+ expect(Interferon::Destinations::Datadog.same_alerts(alert1, [], alert2)).to be true
70
70
  end
71
71
  end
72
72
 
@@ -252,7 +252,7 @@ describe Interferon::Interferon do
252
252
 
253
253
  DEFAULT_OPTIONS = {
254
254
  'evaluation_delay' => nil,
255
- 'notify_audit' => true,
255
+ 'notify_audit' => false,
256
256
  'notify_no_data' => false,
257
257
  'silenced' => {},
258
258
  'thresholds' => nil,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: interferon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Serebryany
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-07-26 00:00:00.000000000 Z
12
+ date: 2017-09-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: dogapi