interferon 0.2.4 → 0.2.5
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.
- checksums.yaml +4 -4
- data/config.example.yaml +2 -0
- data/lib/interferon/alert_dsl.rb +4 -0
- data/lib/interferon/destinations/datadog.rb +17 -9
- data/lib/interferon/version.rb +1 -1
- data/spec/lib/interferon/destinations/datadog_spec.rb +16 -4
- data/spec/lib/interferon_spec.rb +23 -11
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f9e160c8273135fe18dabff0c3a557b265713e87
|
4
|
+
data.tar.gz: 611eac2ede9278bce9e20ad4e906841cd540dcdf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49fc267f05766355000f96775b599b9af7428ce528aaa9becb965e469eb395736ba3af4e9a012265f704399c8c841f877278a6d7d7539c3b7ecd2fa9ff120436
|
7
|
+
data.tar.gz: abfa38af220cb68928ca0ee3f279986ce9161ee17cf9f63ba3c74f27a5bb83e21adbe5d48281053efd3bdfc61195de99cba83cb96249c8bc78fb3a1e9f2866e3
|
data/config.example.yaml
CHANGED
data/lib/interferon/alert_dsl.rb
CHANGED
@@ -95,6 +95,10 @@ module Interferon
|
|
95
95
|
get_or_set(:@evaluation_delay, v, block, nil)
|
96
96
|
end
|
97
97
|
|
98
|
+
def new_host_delay(v = nil, &block)
|
99
|
+
get_or_set(:@new_host_delay, v, block, 300)
|
100
|
+
end
|
101
|
+
|
98
102
|
def require_full_window(v = nil, &block)
|
99
103
|
get_or_set(:@require_full_window, v, block, nil)
|
100
104
|
end
|
@@ -11,6 +11,7 @@ module Interferon::Destinations
|
|
11
11
|
include ::Interferon::Logging
|
12
12
|
|
13
13
|
attr_accessor :concurrency
|
14
|
+
attr_reader :alert_key
|
14
15
|
ALERT_KEY = 'This alert was created via the alerts framework'.freeze
|
15
16
|
|
16
17
|
def initialize(options)
|
@@ -39,6 +40,7 @@ module Interferon::Destinations
|
|
39
40
|
@existing_alerts = nil
|
40
41
|
@max_mute_minutes = options['max_mute_minutes']
|
41
42
|
@dry_run = options['dry_run']
|
43
|
+
@alert_key = options['alert_key'] || ALERT_KEY
|
42
44
|
|
43
45
|
# Datadog communication threads
|
44
46
|
@concurrency = options['concurrency'] || 10
|
@@ -67,7 +69,7 @@ module Interferon::Destinations
|
|
67
69
|
@api_errors ||= []
|
68
70
|
end
|
69
71
|
|
70
|
-
def
|
72
|
+
def generate_message(message, people, options = {})
|
71
73
|
mentions = people.sort.map { |p| "@#{p}" }
|
72
74
|
|
73
75
|
unless options[:notify_recovery]
|
@@ -75,7 +77,7 @@ module Interferon::Destinations
|
|
75
77
|
mentions = "{{^is_recovery}}#{mentions}{{/is_recovery}}"
|
76
78
|
end
|
77
79
|
|
78
|
-
[message,
|
80
|
+
[message, alert_key, mentions].flatten.join("\n")
|
79
81
|
end
|
80
82
|
|
81
83
|
def fetch_existing_alerts
|
@@ -125,7 +127,7 @@ module Interferon::Destinations
|
|
125
127
|
|
126
128
|
# count how many are manually created
|
127
129
|
@stats[:manually_created_alerts] = \
|
128
|
-
@existing_alerts.reject { |_n, a| a['message'].include?(
|
130
|
+
@existing_alerts.reject { |_n, a| a['message'].include?(alert_key) }.length
|
129
131
|
|
130
132
|
log.info(
|
131
133
|
"datadog: found #{@existing_alerts.length} existing alerts; " \
|
@@ -140,7 +142,7 @@ module Interferon::Destinations
|
|
140
142
|
# create a message which includes the notifications
|
141
143
|
# Datadog may have a race condition where alerts created in a bad state may be triggered
|
142
144
|
# during the dry-run creation process. Delete people from dry-run alerts to avoid this
|
143
|
-
message =
|
145
|
+
message = generate_message(
|
144
146
|
alert['message'],
|
145
147
|
people,
|
146
148
|
notify_recovery: alert['notify']['recovery']
|
@@ -163,6 +165,10 @@ module Interferon::Destinations
|
|
163
165
|
alert_options[:evaluation_delay] = alert['evaluation_delay']
|
164
166
|
end
|
165
167
|
|
168
|
+
unless alert['new_host_delay'].nil?
|
169
|
+
alert_options[:new_host_delay] = alert['new_host_delay']
|
170
|
+
end
|
171
|
+
|
166
172
|
unless alert['require_full_window'].nil?
|
167
173
|
alert_options[:require_full_window] = alert['require_full_window']
|
168
174
|
end
|
@@ -303,7 +309,7 @@ EOM
|
|
303
309
|
end
|
304
310
|
|
305
311
|
def remove_alert(alert)
|
306
|
-
if alert['message'].include?(
|
312
|
+
if alert['message'].include?(alert_key)
|
307
313
|
@stats[:alerts_to_be_deleted] += 1
|
308
314
|
log.info("deleting alert: #{alert['name']}")
|
309
315
|
|
@@ -328,7 +334,7 @@ EOM
|
|
328
334
|
def need_update(alert_people_pair, existing_alerts_from_api)
|
329
335
|
alert, people = alert_people_pair
|
330
336
|
existing = existing_alerts_from_api[alert['name']]
|
331
|
-
existing.nil? || !
|
337
|
+
existing.nil? || !same_alerts(alert, people, existing)
|
332
338
|
end
|
333
339
|
|
334
340
|
def self.normalize_monitor_type(monitor_type)
|
@@ -343,12 +349,13 @@ EOM
|
|
343
349
|
normalize_monitor_type(monitor_type_a) == normalize_monitor_type(monitor_type_b)
|
344
350
|
end
|
345
351
|
|
346
|
-
def
|
352
|
+
def same_alerts(alert, people, alert_api_json)
|
347
353
|
prev_alert = {
|
348
|
-
monitor_type: normalize_monitor_type(alert_api_json['type']),
|
354
|
+
monitor_type: self.class.normalize_monitor_type(alert_api_json['type']),
|
349
355
|
query: alert_api_json['query'].strip,
|
350
356
|
message: alert_api_json['message'].strip,
|
351
357
|
evaluation_delay: alert_api_json['options']['evaluation_delay'],
|
358
|
+
new_host_delay: alert_api_json['options']['new_host_delay'],
|
352
359
|
include_tags: alert_api_json['options']['include_tags'],
|
353
360
|
notify_no_data: alert_api_json['options']['notify_no_data'],
|
354
361
|
notify_audit: alert_api_json['options']['notify_audit'],
|
@@ -359,7 +366,7 @@ EOM
|
|
359
366
|
}
|
360
367
|
|
361
368
|
new_alert = {
|
362
|
-
monitor_type: normalize_monitor_type(alert['monitor_type']),
|
369
|
+
monitor_type: self.class.normalize_monitor_type(alert['monitor_type']),
|
363
370
|
query: alert['metric']['datadog_query'],
|
364
371
|
message: generate_message(
|
365
372
|
alert['message'],
|
@@ -367,6 +374,7 @@ EOM
|
|
367
374
|
notify_recovery: alert['notify']['recovery']
|
368
375
|
).strip,
|
369
376
|
evaluation_delay: alert['evaluation_delay'],
|
377
|
+
new_host_delay: alert['new_host_delay'],
|
370
378
|
include_tags: alert['notify']['include_tags'],
|
371
379
|
notify_no_data: alert['notify_no_data'],
|
372
380
|
notify_audit: alert['notify']['audit'],
|
data/lib/interferon/version.rb
CHANGED
@@ -26,6 +26,12 @@ describe Interferon::Destinations::Datadog do
|
|
26
26
|
base_datadog_config.merge('max_mute_minutes' => max_mute_minutes)
|
27
27
|
)
|
28
28
|
end
|
29
|
+
let(:datadog_alert_key) do
|
30
|
+
Interferon::Destinations::Datadog.new(
|
31
|
+
base_datadog_config.merge('alert_key' => mock_custom_alert_key)
|
32
|
+
)
|
33
|
+
end
|
34
|
+
let(:mock_custom_alert_key) { 'My custom alert key' }
|
29
35
|
let(:mock_alert_id) { 123 }
|
30
36
|
let(:mock_alert) do
|
31
37
|
{
|
@@ -148,20 +154,26 @@ describe Interferon::Destinations::Datadog do
|
|
148
154
|
let(:people) { %w(userA userB) }
|
149
155
|
|
150
156
|
it 'adds the ALERT_KEY to the message' do
|
151
|
-
expect(
|
157
|
+
expect(datadog.generate_message(message, people)).to include(
|
152
158
|
Interferon::Destinations::Datadog::ALERT_KEY
|
153
159
|
)
|
154
160
|
end
|
155
161
|
|
162
|
+
it 'prefers a custom alert_key if provided' do
|
163
|
+
expect(datadog_alert_key.generate_message(message, people)).to include(
|
164
|
+
mock_custom_alert_key
|
165
|
+
)
|
166
|
+
end
|
167
|
+
|
156
168
|
it 'adds a mention to people' do
|
157
|
-
expect(
|
169
|
+
expect(datadog.generate_message(message, people)).to include(
|
158
170
|
*people.map { |person| "@#{person}" }
|
159
171
|
)
|
160
172
|
end
|
161
173
|
|
162
174
|
it 'does not add ^is_recovery template variable when notify_recovery is true' do
|
163
175
|
expect(
|
164
|
-
|
176
|
+
datadog.generate_message(
|
165
177
|
message, people, notify_recovery: true
|
166
178
|
)
|
167
179
|
).not_to include('{{^is_recovery}}')
|
@@ -169,7 +181,7 @@ describe Interferon::Destinations::Datadog do
|
|
169
181
|
|
170
182
|
it 'adds a ^is_recovery template variable when notify_recovery is false' do
|
171
183
|
expect(
|
172
|
-
|
184
|
+
datadog.generate_message(
|
173
185
|
message, people, notify_recovery: false
|
174
186
|
)
|
175
187
|
).to include('{{^is_recovery}}')
|
data/spec/lib/interferon_spec.rb
CHANGED
@@ -7,9 +7,14 @@ include Interferon
|
|
7
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
|
+
let(:datadog) do
|
11
|
+
Interferon::Destinations::Datadog.new(
|
12
|
+
'app_key' => 'TEST_APP_KEY', 'api_key' => 'TEST_API_KEY'
|
13
|
+
)
|
14
|
+
end
|
10
15
|
|
11
16
|
shared_examples_for 'alert_option' do |alert_option, same_value, different_value, alert_dsl|
|
12
|
-
let(:json_message) { 'message' + "\n#{
|
17
|
+
let(:json_message) { 'message' + "\n#{datadog.alert_key}" }
|
13
18
|
let(:alert) do
|
14
19
|
alert_dsl_path = alert_dsl.nil? ? alert_option : alert_dsl
|
15
20
|
create_test_alert('name1', 'testquery', 'message', alert_dsl_path => same_value)
|
@@ -27,46 +32,46 @@ describe Interferon::Destinations::Datadog do
|
|
27
32
|
|
28
33
|
context 'when the options are the same' do
|
29
34
|
it 'should return true' do
|
30
|
-
expect(
|
35
|
+
expect(datadog.same_alerts(alert, [], alert_same)).to be true
|
31
36
|
end
|
32
37
|
end
|
33
38
|
|
34
39
|
context 'when the options are the different' do
|
35
40
|
it 'should return false' do
|
36
|
-
expect(
|
41
|
+
expect(datadog.same_alerts(alert, [], alert_diff)).to be false
|
37
42
|
end
|
38
43
|
end
|
39
44
|
end
|
40
45
|
|
41
46
|
describe '#same_alerts' do
|
42
|
-
let(:json_message) { 'message' + "\n#{
|
47
|
+
let(:json_message) { 'message' + "\n#{datadog.alert_key}" }
|
43
48
|
|
44
49
|
it 'detects a no change if alert message is the same' do
|
45
50
|
alert1 = create_test_alert('name1', 'testquery', 'message')
|
46
51
|
alert2 = mock_alert_json('name2', 'testquery', json_message)
|
47
52
|
|
48
|
-
expect(
|
53
|
+
expect(datadog.same_alerts(alert1, [], alert2)).to be true
|
49
54
|
end
|
50
55
|
|
51
56
|
it 'detects a change if alert message is different' do
|
52
57
|
alert1 = create_test_alert('name1', 'testquery', 'message2')
|
53
58
|
alert2 = mock_alert_json('name2', 'testquery', json_message)
|
54
59
|
|
55
|
-
expect(
|
60
|
+
expect(datadog.same_alerts(alert1, [], alert2)).to be false
|
56
61
|
end
|
57
62
|
|
58
63
|
it 'detects no change if datadog query is the same' do
|
59
64
|
alert1 = create_test_alert('name1', 'testquery', 'message')
|
60
65
|
alert2 = mock_alert_json('name2', 'testquery', json_message)
|
61
66
|
|
62
|
-
expect(
|
67
|
+
expect(datadog.same_alerts(alert1, [], alert2)).to be true
|
63
68
|
end
|
64
69
|
|
65
70
|
it 'detects a change if datadog query is different' do
|
66
71
|
alert1 = create_test_alert('name1', 'testquery1', 'message')
|
67
72
|
alert2 = mock_alert_json('name2', 'testquery2', json_message)
|
68
73
|
|
69
|
-
expect(
|
74
|
+
expect(datadog.same_alerts(alert1, [], alert2)).to be false
|
70
75
|
end
|
71
76
|
|
72
77
|
context 'notify_no_data option' do
|
@@ -89,6 +94,10 @@ describe Interferon::Destinations::Datadog do
|
|
89
94
|
it_behaves_like('alert_option', 'evaluation_delay', nil, 300)
|
90
95
|
end
|
91
96
|
|
97
|
+
context 'new_host_delay option' do
|
98
|
+
it_behaves_like('alert_option', 'new_host_delay', 400, 400)
|
99
|
+
end
|
100
|
+
|
92
101
|
context 'thresholds option' do
|
93
102
|
it_behaves_like('alert_option', 'thresholds', nil, 'critical' => 1)
|
94
103
|
end
|
@@ -111,7 +120,7 @@ describe Interferon::Destinations::Datadog do
|
|
111
120
|
'name2', 'testquery', json_message, 'metric alert', [1], 'silenced' => { '*' => nil }
|
112
121
|
)
|
113
122
|
|
114
|
-
expect(
|
123
|
+
expect(datadog.same_alerts(alert1, [], alert2)).to be true
|
115
124
|
end
|
116
125
|
end
|
117
126
|
|
@@ -283,7 +292,7 @@ describe Interferon::Destinations::Datadog do
|
|
283
292
|
end
|
284
293
|
|
285
294
|
def mock_existing_alerts
|
286
|
-
mock_message =
|
295
|
+
mock_message = datadog.alert_key
|
287
296
|
alert1 = mock_alert_json('name1', 'testquery1', mock_message)
|
288
297
|
alert2 = mock_alert_json('name2', 'testquery2', mock_message)
|
289
298
|
{ 'name1' => alert1, 'name2' => alert2 }
|
@@ -294,6 +303,7 @@ describe Interferon::Destinations::Datadog do
|
|
294
303
|
|
295
304
|
def initialize(the_existing_alerts)
|
296
305
|
@existing_alerts = the_existing_alerts
|
306
|
+
@alert_key = ALERT_KEY
|
297
307
|
end
|
298
308
|
|
299
309
|
def create_alert(alert, _people)
|
@@ -305,6 +315,7 @@ describe Interferon::Destinations::Datadog do
|
|
305
315
|
|
306
316
|
DEFAULT_OPTIONS = {
|
307
317
|
'evaluation_delay' => nil,
|
318
|
+
'new_host_delay' => 300,
|
308
319
|
'notify_audit' => false,
|
309
320
|
'notify_no_data' => false,
|
310
321
|
'silenced' => {},
|
@@ -330,7 +341,7 @@ describe Interferon::Destinations::Datadog do
|
|
330
341
|
create_test_alert(
|
331
342
|
mock_alert_json['name'],
|
332
343
|
mock_alert_json['query'],
|
333
|
-
mock_alert_json['message'].sub(/#{
|
344
|
+
mock_alert_json['message'].sub(/#{datadog.alert_key}$/, ''),
|
334
345
|
mock_alert_json['options']
|
335
346
|
)
|
336
347
|
end
|
@@ -358,6 +369,7 @@ describe Interferon::Destinations::Datadog do
|
|
358
369
|
alert_dsl.no_data_timeframe(options['no_data_timeframe'])
|
359
370
|
alert_dsl.notify_no_data(options['notify_no_data'])
|
360
371
|
alert_dsl.evaluation_delay(options['evaluation_delay'])
|
372
|
+
alert_dsl.new_host_delay(options['new_host_delay'])
|
361
373
|
alert_dsl.require_full_window(options['require_full_window'])
|
362
374
|
alert_dsl.thresholds(options['thresholds'])
|
363
375
|
alert_dsl.timeout(options['timeout'])
|
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.2.
|
4
|
+
version: 0.2.5
|
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-
|
12
|
+
date: 2017-10-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: dogapi
|