interferon 0.1.0 → 0.1.3

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.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +4 -0
  3. data/.rubocop_todo.yml +83 -0
  4. data/.travis.yml +4 -1
  5. data/bin/interferon +10 -9
  6. data/interferon.gemspec +18 -17
  7. data/lib/interferon/alert.rb +4 -10
  8. data/lib/interferon/alert_dsl.rb +12 -7
  9. data/lib/interferon/destinations/datadog.rb +103 -103
  10. data/lib/interferon/group_sources/filesystem.rb +5 -5
  11. data/lib/interferon/host_sources/aws_dynamo.rb +17 -19
  12. data/lib/interferon/host_sources/aws_elasticache.rb +20 -22
  13. data/lib/interferon/host_sources/aws_rds.rb +33 -33
  14. data/lib/interferon/host_sources/optica.rb +12 -10
  15. data/lib/interferon/host_sources/optica_services.rb +17 -15
  16. data/lib/interferon/host_sources/test_host_source.rb +1 -1
  17. data/lib/interferon/loaders.rb +4 -5
  18. data/lib/interferon/logging.rb +2 -3
  19. data/lib/interferon/version.rb +1 -1
  20. data/lib/interferon/work_hours_helper.rb +5 -5
  21. data/lib/interferon.rb +79 -80
  22. data/script/pre-commit +15 -20
  23. data/spec/fixtures/loaders/host_sources/test_host_source.rb +1 -1
  24. data/spec/fixtures/loaders/test_sources/order_test_source.rb +1 -1
  25. data/spec/fixtures/loaders/test_sources/test_source.rb +1 -1
  26. data/spec/fixtures/loaders2/test_sources/order_test_source.rb +1 -1
  27. data/spec/fixtures/loaders2/test_sources/secondary_source.rb +1 -1
  28. data/spec/fixtures/loaders2/test_sources/test_source.rb +1 -2
  29. data/spec/helpers/logging_helper.rb +2 -2
  30. data/spec/helpers/mock_alert.rb +1 -1
  31. data/spec/helpers/optica_helper.rb +70 -70
  32. data/spec/lib/interferon/destinations/datadog_spec.rb +58 -59
  33. data/spec/lib/interferon/group_sources/filesystem_spec.rb +29 -24
  34. data/spec/lib/interferon/host_sources/optica_services_spec.rb +11 -9
  35. data/spec/lib/interferon/host_sources/optica_spec.rb +6 -3
  36. data/spec/lib/interferon/loaders_spec.rb +19 -15
  37. data/spec/lib/interferon_spec.rb +61 -59
  38. data/spec/lib/work_hours_helper_spec.rb +15 -15
  39. data/spec/spec_helper.rb +1 -1
  40. metadata +61 -65
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a9fbb5fdb83e9978e96990983e1c815fd18e7cdc
4
+ data.tar.gz: 0d5b080a2ad8dbdd8a16edd1bcae27aadfb6c366
5
+ SHA512:
6
+ metadata.gz: 542ec78306622d95e55f698f2c0b35b7f0a8365a8eb0f2f85d0faff851fd22f5ddaef5d5b5c2f8adf585f0a297d23f0684cf5293122073729bd326cd23dab530
7
+ data.tar.gz: 271d43056cc9be797fb8e4ae3f98d4370518481f71bcf4b1f0d749b09e1433e36666b9ca701439d4bc6167a9857a2c53977836131d7f5a55355e44fa6d140c9d
data/.rubocop.yml ADDED
@@ -0,0 +1,4 @@
1
+ # REVIEWERS airbnb/security airbnb/rubocop
2
+
3
+ inherit_from:
4
+ - .rubocop_todo.yml
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,83 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config --exclude-limit 50000`
3
+ # on 2017-06-05 13:58:15 -0700 using RuboCop version 0.41.2.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ Metrics/AbcSize:
10
+ Enabled: false
11
+
12
+ Metrics/ClassLength:
13
+ Enabled: false
14
+
15
+ Metrics/CyclomaticComplexity:
16
+ Enabled: false
17
+ Max: 6
18
+
19
+ # Configuration parameters: AllowHeredoc, AllowURI, URISchemes.
20
+ # URISchemes: http, https
21
+ Metrics/LineLength:
22
+ Max: 100
23
+ AllowURI: true
24
+
25
+ # Configuration parameters: CountComments.
26
+ Metrics/MethodLength:
27
+ Enabled: false
28
+
29
+ # Configuration parameters: CountKeywordArgs.
30
+ Metrics/ParameterLists:
31
+ Enabled: false
32
+ Max: 5
33
+
34
+ Metrics/PerceivedComplexity:
35
+ Enabled: false
36
+ Max: 7
37
+
38
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
39
+ # SupportedStyles: nested, compact
40
+ Style/ClassAndModuleChildren:
41
+ Enabled: false
42
+ EnforcedStyle: nested
43
+ SupportedStyles:
44
+ - nested
45
+ - compact
46
+
47
+ Style/Documentation:
48
+ Enabled: false
49
+
50
+ Style/DoubleNegation:
51
+ Enabled: false
52
+
53
+ # Offense count: 3
54
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
55
+ # SupportedStyles: format, sprintf, percent
56
+ Style/FormatString:
57
+ Enabled: false
58
+ EnforcedStyle: format
59
+ SupportedStyles:
60
+ - format
61
+ - sprintf
62
+ - percent
63
+
64
+ # Offense count: 3
65
+ # Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist.
66
+ # NamePrefix: is_, has_, have_
67
+ # NamePrefixBlacklist: is_, has_, have_
68
+ # NameWhitelist: is_a?
69
+ Style/PredicateName:
70
+ Enabled: false
71
+ NamePrefix:
72
+ - is_
73
+ - has_
74
+ - have_
75
+ NamePrefixBlacklist:
76
+ - is_
77
+ - has_
78
+ - have_
79
+
80
+
81
+ Style/TrailingCommaInLiteral:
82
+ Enabled: true
83
+ EnforcedStyleForMultiline: consistent_comma
data/.travis.yml CHANGED
@@ -1,7 +1,10 @@
1
+ ---
1
2
  language: ruby
2
3
  sudo: false
3
4
  cache: bundler
4
- script: bundle exec rspec
5
+ script:
6
+ - bundle exec rspec
7
+ - bundle exec rubocop
5
8
  rvm:
6
9
  - 1.9.3
7
10
  - 2.1.10
data/bin/interferon CHANGED
@@ -4,13 +4,13 @@ require 'yaml'
4
4
  require 'optparse'
5
5
  require 'interferon'
6
6
 
7
- options={}
7
+ options = {}
8
8
 
9
9
  # set command line options
10
10
  optparse = OptionParser.new do |opts|
11
- opts.banner = %{Usage: interferon --config /path/to/interferon/config}
11
+ opts.banner = %(Usage: interferon --config /path/to/interferon/config)
12
12
 
13
- opts.on('-c config','--config config', String, 'Path to interferon config') do |key,value|
13
+ opts.on('-c config', '--config config', String, 'Path to interferon config') do |key, _value|
14
14
  options[:config] = key
15
15
  end
16
16
 
@@ -26,7 +26,7 @@ end
26
26
 
27
27
  def parseconfig(filename)
28
28
  begin
29
- c = YAML::parse(File.read(filename))
29
+ c = YAML.parse(File.read(filename))
30
30
  rescue Errno::ENOENT => e
31
31
  raise ArgumentError, "config file does not exist:\n#{e.inspect}"
32
32
  rescue Errno::EACCES => e
@@ -34,7 +34,7 @@ def parseconfig(filename)
34
34
  rescue YAML::SyntaxError => e
35
35
  raise "config file #{filename} contains invalid YAML:\n#{e.inspect}"
36
36
  end
37
- return c.to_ruby
37
+ c.to_ruby
38
38
  end
39
39
 
40
40
  # parse command line arguments
@@ -46,8 +46,8 @@ end
46
46
 
47
47
  # validate that required options are present
48
48
  config = parseconfig(options[:config])
49
- %w{alerts_repo_path host_sources destinations}.each do |req|
50
- unless config.include?(req) && ! config[req].empty?
49
+ %w(alerts_repo_path host_sources destinations).each do |req|
50
+ unless config.include?(req) && !config[req].empty?
51
51
  puts "config file has no #{req} defined; exiting"
52
52
  exit 2
53
53
  end
@@ -59,8 +59,9 @@ a = Interferon::Interferon.new(
59
59
  config['alerts_repo_path'],
60
60
  config['group_sources'] || {},
61
61
  config['host_sources'],
62
- config['destinations'])
62
+ config['destinations']
63
+ )
63
64
 
64
65
  a.run(options[:dry_run])
65
66
 
66
- puts "interferon signaling complete!"
67
+ puts 'interferon signaling complete!'
data/interferon.gemspec CHANGED
@@ -4,27 +4,28 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'interferon/version'
5
5
 
6
6
  Gem::Specification.new do |gem|
7
- gem.name = "interferon"
7
+ gem.name = 'interferon'
8
8
  gem.version = Interferon::VERSION
9
- gem.authors = ["Igor Serebryany", "Jimmy Ngo"]
10
- gem.email = ["igor.serebryany@airbnb.com", "jimmy.ngo@airbnb.com"]
11
- gem.description = %q{: Store metrics alerts in code!}
12
- gem.summary = %q{: Store metrics alerts in code!}
13
- gem.homepage = "https://www.github.com/airbnb/interferon"
9
+ gem.authors = ['Igor Serebryany', 'Jimmy Ngo']
10
+ gem.email = ['igor.serebryany@airbnb.com', 'jimmy.ngo@airbnb.com']
11
+ gem.description = %(: Store metrics alerts in code!)
12
+ gem.summary = %(: Store metrics alerts in code!)
13
+ gem.homepage = 'https://www.github.com/airbnb/interferon'
14
14
  gem.licenses = ['MIT']
15
15
 
16
- gem.files = `git ls-files`.split($/)
17
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
18
18
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
19
 
20
- gem.add_runtime_dependency "dogapi", "~> 1.11", ">= 1.11.1"
21
- gem.add_runtime_dependency "aws-sdk", "~> 1.35", ">= 1.35.1"
22
- gem.add_runtime_dependency "dogstatsd-ruby", "~> 1.4", ">= 1.4.1"
23
- gem.add_runtime_dependency "diffy", "~> 3.1.0", ">= 3.1.0"
24
- gem.add_runtime_dependency "parallel", "~> 1.9", ">= 1.9.0"
25
- gem.add_runtime_dependency "nokogiri", "< 1.7.0"
26
- gem.add_runtime_dependency "tzinfo", "~> 1.2.2", ">= 1.2.2"
20
+ gem.add_runtime_dependency 'dogapi', '~> 1.27', '>= 1.27.0'
21
+ gem.add_runtime_dependency 'aws-sdk', '~> 1.35', '>= 1.35.1'
22
+ gem.add_runtime_dependency 'dogstatsd-ruby', '~> 1.4', '>= 1.4.1'
23
+ gem.add_runtime_dependency 'diffy', '~> 3.1.0', '>= 3.1.0'
24
+ gem.add_runtime_dependency 'parallel', '~> 1.9', '>= 1.9.0'
25
+ gem.add_runtime_dependency 'nokogiri', '< 1.7.0'
26
+ gem.add_runtime_dependency 'tzinfo', '~> 1.2.2', '>= 1.2.2'
27
27
 
28
- gem.add_development_dependency "rspec", "~> 3.2"
29
- gem.add_development_dependency "pry", "~> 0.10"
28
+ gem.add_development_dependency 'rspec', '~> 3.2'
29
+ gem.add_development_dependency 'pry', '~> 0.10'
30
+ gem.add_development_dependency 'rubocop', '0.41.2'
30
31
  end
@@ -23,27 +23,21 @@ module Interferon
23
23
  end
24
24
 
25
25
  def change_name(name)
26
- unless @dsl
27
- raise "This alert has not yet been evaluated"
28
- end
26
+ raise 'This alert has not yet been evaluated' unless @dsl
29
27
 
30
28
  @dsl.name(name)
31
29
  end
32
30
 
33
31
  def silence
34
- unless @dsl
35
- raise "This alert has not yet been evaluated"
36
- end
32
+ raise 'This alert has not yet been evaluated' unless @dsl
37
33
 
38
34
  @dsl.silenced(true)
39
35
  end
40
36
 
41
37
  def [](attr)
42
- unless @dsl
43
- raise "This alert has not yet been evaluated"
44
- end
38
+ raise 'This alert has not yet been evaluated' unless @dsl
45
39
 
46
- return @dsl.send(attr)
40
+ @dsl.send(attr)
47
41
  end
48
42
  end
49
43
  end
@@ -6,15 +6,16 @@ module Interferon
6
6
  @hostinfo = hostinfo
7
7
  end
8
8
 
9
- def method_missing(meth, *args, &block)
9
+ def method_missing(meth, *_args)
10
10
  raise ArgumentError, "No such alerts field '#{meth}'"
11
11
  end
12
12
 
13
13
  def [](arg)
14
- self.send(arg)
14
+ send(arg)
15
15
  end
16
16
 
17
17
  private
18
+
18
19
  def get_or_set(field, val, block, default)
19
20
  if val.nil? && block.nil?
20
21
  f = instance_variable_get(field)
@@ -33,7 +34,7 @@ module Interferon
33
34
  include DSLMixin
34
35
 
35
36
  def name(v = nil, &block)
36
- get_or_set(:@name, v, block, '') { |val| val.strip }
37
+ get_or_set(:@name, v, block, '', &:strip)
37
38
  end
38
39
 
39
40
  def message(v = nil, &block)
@@ -53,7 +54,7 @@ module Interferon
53
54
  if val.is_a? Hash
54
55
  val
55
56
  elsif val == true
56
- { "*" => nil }
57
+ { '*' => nil }
57
58
  else
58
59
  {}
59
60
  end
@@ -90,15 +91,19 @@ module Interferon
90
91
  get_or_set(:@thresholds, v, block, nil)
91
92
  end
92
93
 
94
+ def evaluation_delay(v = nil, &block)
95
+ get_or_set(:@evaluation_delay, v, block, nil)
96
+ end
97
+
93
98
  def require_full_window(v = nil, &block)
94
99
  get_or_set(:@require_full_window, v, block, nil)
95
100
  end
96
101
 
97
- def notify(v = nil)
102
+ def notify(_v = nil)
98
103
  @notify ||= NotifyDSL.new(@hostinfo)
99
104
  end
100
105
 
101
- def metric(v = nil)
106
+ def metric(_v = nil)
102
107
  @metric ||= MetricDSL.new(@hostinfo)
103
108
  end
104
109
  end
@@ -123,7 +128,7 @@ module Interferon
123
128
  include DSLMixin
124
129
 
125
130
  def datadog_query(v = nil, &block)
126
- get_or_set(:@datadog_query, v, block, '') { |val| val.strip }
131
+ get_or_set(:@datadog_query, v, block, '', &:strip)
127
132
  end
128
133
  end
129
134
  end
@@ -11,10 +11,10 @@ module Interferon::Destinations
11
11
  include ::Interferon::Logging
12
12
 
13
13
  attr_accessor :concurrency
14
- ALERT_KEY = 'This alert was created via the alerts framework'
14
+ ALERT_KEY = 'This alert was created via the alerts framework'.freeze
15
15
 
16
16
  def initialize(options)
17
- %w{app_key api_key}.each do |req|
17
+ %w(app_key api_key).each do |req|
18
18
  unless options[req]
19
19
  raise ArgumentError, "missing required argument #{req}"
20
20
  end
@@ -48,17 +48,17 @@ module Interferon::Destinations
48
48
  @retries = options['retries'] || 3
49
49
 
50
50
  @stats = {
51
- :alerts_created => 0,
52
- :alerts_to_be_created => 0,
53
- :alerts_updated => 0,
54
- :alerts_to_be_updated => 0,
55
- :alerts_deleted => 0,
56
- :alerts_to_be_deleted => 0,
57
- :alerts_silenced => 0,
58
- :api_successes => 0,
59
- :api_client_errors => 0,
60
- :api_unknown_errors => 0,
61
- :manually_created_alerts => 0,
51
+ alerts_created: 0,
52
+ alerts_to_be_created: 0,
53
+ alerts_updated: 0,
54
+ alerts_to_be_updated: 0,
55
+ alerts_deleted: 0,
56
+ alerts_to_be_deleted: 0,
57
+ alerts_silenced: 0,
58
+ api_successes: 0,
59
+ api_client_errors: 0,
60
+ api_unknown_errors: 0,
61
+ manually_created_alerts: 0,
62
62
  }
63
63
  end
64
64
 
@@ -67,10 +67,10 @@ module Interferon::Destinations
67
67
  end
68
68
 
69
69
  def generate_message(message, people)
70
- [message, ALERT_KEY, people.map{ |p| "@#{p}" }].flatten.join("\n")
70
+ [message, ALERT_KEY, people.map { |p| "@#{p}" }].flatten.join("\n")
71
71
  end
72
72
 
73
- def get_existing_alerts
73
+ def fetch_existing_alerts
74
74
  alerts = Queue.new
75
75
  has_more = true
76
76
 
@@ -84,26 +84,24 @@ module Interferon::Destinations
84
84
  log.info("Failed to retrieve existing alerts from datadog. #{code}: #{resp[1].inspect}")
85
85
  else
86
86
  alerts_page = resp[1]
87
- if alerts_page.length < @page_size
88
- has_more = false
89
- end
87
+ has_more = false if alerts_page.length < @page_size
90
88
  alerts_page.map { |alert| alerts.push(alert) }
91
89
  successful = true
92
90
  break
93
91
  end
94
92
  end
95
93
 
96
- if !successful
94
+ unless successful
97
95
  # Out of retries
98
- raise "Retries exceeded for fetching data from datadog."
96
+ raise 'Retries exceeded for fetching data from datadog.'
99
97
  end
100
98
  end
101
- alerts.size.times.map { alerts.pop }
99
+ Array.new(alerts.size) { alerts.pop }
102
100
  end
103
101
 
104
102
  def existing_alerts
105
103
  unless @existing_alerts
106
- alerts = get_existing_alerts
104
+ alerts = fetch_existing_alerts
107
105
 
108
106
  # key alerts by name
109
107
  @existing_alerts = {}
@@ -119,9 +117,9 @@ module Interferon::Destinations
119
117
 
120
118
  # count how many are manually created
121
119
  @stats[:manually_created_alerts] = \
122
- @existing_alerts.reject{|n,a| a['message'].include?(ALERT_KEY)}.length
120
+ @existing_alerts.reject { |_n, a| a['message'].include?(ALERT_KEY) }.length
123
121
 
124
- log.info "datadog: found %d existing alerts; %d were manually created" % [
122
+ log.info 'datadog: found %d existing alerts; %d were manually created' % [
125
123
  @existing_alerts.length,
126
124
  @stats[:manually_created_alerts],
127
125
  ]
@@ -138,18 +136,22 @@ module Interferon::Destinations
138
136
 
139
137
  # create the hash of options to send to datadog
140
138
  alert_options = {
141
- :notify_audit => alert['notify']['audit'],
142
- :notify_no_data => alert['notify_no_data'],
143
- :no_data_timeframe => alert['no_data_timeframe'],
144
- :silenced => alert['silenced'],
145
- :timeout_h => alert['timeout_h'],
139
+ notify_audit: alert['notify']['audit'],
140
+ notify_no_data: alert['notify_no_data'],
141
+ no_data_timeframe: alert['no_data_timeframe'],
142
+ silenced: alert['silenced'],
143
+ timeout_h: alert['timeout_h'],
146
144
  }
147
145
 
148
- if !alert['require_full_window'].nil?
146
+ unless alert['evaluation_delay'].nil?
147
+ alert_options[:evaluation_delay] = alert['evaluation_delay']
148
+ end
149
+
150
+ unless alert['require_full_window'].nil?
149
151
  alert_options[:require_full_window] = alert['require_full_window']
150
152
  end
151
153
 
152
- if !alert['thresholds'].nil?
154
+ unless alert['thresholds'].nil?
153
155
  alert_options[:thresholds] = alert['thresholds']
154
156
  end
155
157
 
@@ -171,11 +173,11 @@ module Interferon::Destinations
171
173
  log_datadog_response_code(resp, code, action, alert)
172
174
 
173
175
  # assume this was a success
174
- if !(code >= 400 || code == -1)
176
+ unless code >= 400 || code == -1
175
177
  # assume this was a success
176
178
  @stats[:alerts_created] += 1 if action == :creating
177
179
  @stats[:alerts_updated] += 1 if action == :updating
178
- @stats[:alerts_silenced] += 1 if !alert_options[:silenced].empty?
180
+ @stats[:alerts_silenced] += 1 unless alert_options[:silenced].empty?
179
181
  end
180
182
 
181
183
  id = resp[1].nil? ? nil : [resp[1]['id']]
@@ -198,17 +200,17 @@ EOM
198
200
  @dog.monitor(
199
201
  alert['monitor_type'],
200
202
  datadog_query,
201
- :name => alert['name'],
202
- :message => @dry_run ? generate_message(alert, []) : message,
203
- :options => alert_options,
203
+ name: alert['name'],
204
+ message: @dry_run ? generate_message(alert, []) : message,
205
+ options: alert_options
204
206
  )
205
207
  end
206
208
 
207
209
  def update_datadog_alert(alert, datadog_query, message, alert_options, existing_alert)
208
- @stats[:alerts_to_be_updated] += 1
209
- id = existing_alert['id'][0]
210
+ @stats[:alerts_to_be_updated] += 1
211
+ id = existing_alert['id'][0]
210
212
 
211
- new_alert_text = <<-EOM.strip
213
+ new_alert_text = <<-EOM.strip
212
214
  Query:
213
215
  #{datadog_query.strip}
214
216
  Message:
@@ -216,7 +218,7 @@ Message:
216
218
  Options:
217
219
  #{alert_options}
218
220
  EOM
219
- existing_alert_text = <<-EOM.strip
221
+ existing_alert_text = <<-EOM.strip
220
222
  Query:
221
223
  #{existing_alert['query'].strip}
222
224
  Message:
@@ -224,63 +226,60 @@ Message:
224
226
  Options:
225
227
  #{alert_options}
226
228
  EOM
227
- diff = Diffy::Diff.new(existing_alert_text, new_alert_text, :context=>1)
228
- log.info("updating existing alert #{id} (#{alert['name']}):\n#{diff}")
229
-
230
- if @dry_run
229
+ diff = Diffy::Diff.new(existing_alert_text, new_alert_text, context: 1)
230
+ log.info("updating existing alert #{id} (#{alert['name']}):\n#{diff}")
231
+
232
+ if @dry_run
233
+ resp = @dog.monitor(
234
+ alert['monitor_type'],
235
+ datadog_query,
236
+ name: alert['name'],
237
+ message: generate_message(alert, []),
238
+ options: alert_options
239
+ )
240
+ elsif alert['monitor_type'] == existing_alert['type']
241
+ resp = @dog.update_monitor(
242
+ id,
243
+ datadog_query,
244
+ name: alert['name'],
245
+ message: message,
246
+ options: alert_options
247
+ )
248
+
249
+ # Unmute existing alerts that have been unsilenced.
250
+ # Datadog does not allow updates to silencing via the update_alert API call.
251
+ if !existing_alert['options']['silenced'].empty? && alert_options[:silenced].empty?
252
+ @dog.unmute_monitor(id)
253
+ end
254
+ else
255
+ # Need to recreate alert with new monitor type
256
+ resp = @dog.delete_monitor(id)
257
+ code = resp[0].to_i
258
+ unless code >= 300 || code == -1
231
259
  resp = @dog.monitor(
232
260
  alert['monitor_type'],
233
261
  datadog_query,
234
- :name => alert['name'],
235
- :message => generate_message(alert, []),
236
- :options => alert_options,
262
+ name: alert['name'],
263
+ message: message,
264
+ options: alert_options
237
265
  )
238
- else
239
- if alert['monitor_type'] == existing_alert['type']
240
- resp = @dog.update_monitor(
241
- id,
242
- datadog_query,
243
- :name => alert['name'],
244
- :message => message,
245
- :options => alert_options,
246
- )
247
-
248
- # Unmute existing alerts that have been unsilenced.
249
- # Datadog does not allow updates to silencing via the update_alert API call.
250
- if !existing_alert['options']['silenced'].empty? && alert_options[:silenced].empty?
251
- @dog.unmute_monitor(id)
252
- end
253
- else
254
- # Need to recreate alert with new monitor type
255
- resp = @dog.delete_monitor(id)
256
- code = resp[0].to_i
257
- if !(code >= 300 || code == -1)
258
- resp = @dog.monitor(
259
- alert['monitor_type'],
260
- datadog_query,
261
- :name => alert['name'],
262
- :message => message,
263
- :options => alert_options,
264
- )
265
- end
266
- end
267
266
  end
268
- resp
267
+ end
268
+ resp
269
269
  end
270
270
 
271
-
272
271
  def remove_alert(alert)
273
272
  if alert['message'].include?(ALERT_KEY)
274
273
  @stats[:alerts_to_be_deleted] += 1
275
274
  log.info("deleting alert: #{alert['name']}")
276
275
 
277
- if !@dry_run
276
+ unless @dry_run
278
277
  alert['id'].each do |alert_id|
279
278
  resp = @dog.delete_monitor(alert_id)
280
279
  code = resp[0].to_i
281
280
  log_datadog_response_code(resp, code, :deleting)
282
281
 
283
- if !(code >= 300 || code == -1)
282
+ unless code >= 300 || code == -1
284
283
  # assume this was a success
285
284
  @stats[:alerts_deleted] += 1
286
285
  end
@@ -292,18 +291,20 @@ EOM
292
291
  end
293
292
 
294
293
  def report_stats
295
- @stats.each do |k,v|
294
+ @stats.each do |k, v|
296
295
  statsd.gauge("datadog.#{k}", v)
297
296
  end
298
297
 
299
- log.info "datadog: successfully created (%d/%d), updated (%d/%d), and deleted (%d/%d) alerts" % [
300
- @stats[:alerts_created],
301
- @stats[:alerts_to_be_created],
302
- @stats[:alerts_updated],
303
- @stats[:alerts_to_be_updated],
304
- @stats[:alerts_deleted],
305
- @stats[:alerts_to_be_deleted],
306
- ]
298
+ log.info(
299
+ 'datadog: successfully created (%d/%d), updated (%d/%d), and deleted (%d/%d) alerts' % [
300
+ @stats[:alerts_created],
301
+ @stats[:alerts_to_be_created],
302
+ @stats[:alerts_updated],
303
+ @stats[:alerts_to_be_updated],
304
+ @stats[:alerts_deleted],
305
+ @stats[:alerts_to_be_deleted],
306
+ ]
307
+ )
307
308
  end
308
309
 
309
310
  def remove_alert_by_id(alert_id)
@@ -314,7 +315,7 @@ EOM
314
315
  log_datadog_response_code(resp, code, :deleting)
315
316
  end
316
317
 
317
- def log_datadog_response_code(resp, code, action, alert=nil)
318
+ def log_datadog_response_code(resp, code, action, alert = nil)
318
319
  # log whenever we've encountered errors
319
320
  if code != 200 && !alert.nil?
320
321
  api_errors << "#{code} on alert #{alert['name']}"
@@ -323,10 +324,10 @@ EOM
323
324
  # client error
324
325
  if code == 400
325
326
  @stats[:api_client_errors] += 1
326
- if !alert.nil?
327
- statsd.gauge('datadog.api.unknown_error', 0, :tags => ["alert:#{alert}"])
328
- statsd.gauge('datadog.api.client_error', 1, :tags => ["alert:#{alert}"])
329
- statsd.gauge('datadog.api.success', 0, :tags => ["alert:#{alert}"])
327
+ unless alert.nil?
328
+ statsd.gauge('datadog.api.unknown_error', 0, tags: ["alert:#{alert}"])
329
+ statsd.gauge('datadog.api.client_error', 1, tags: ["alert:#{alert}"])
330
+ statsd.gauge('datadog.api.success', 0, tags: ["alert:#{alert}"])
330
331
  log.error("client error while #{action} alert '#{alert['name']}';" \
331
332
  " query was '#{alert['metric']['datadog_query']}'" \
332
333
  " response was #{resp[0]}:'#{resp[1].inspect}'")
@@ -335,23 +336,22 @@ EOM
335
336
  # unknown (prob. datadog) error:
336
337
  elsif code > 400 || code == -1
337
338
  @stats[:api_unknown_errors] += 1
338
- if !alert.nil?
339
- statsd.gauge('datadog.api.unknown_error', 1, :tags => ["alert:#{alert}"])
340
- statsd.gauge('datadog.api.client_error', 0, :tags => ["alert:#{alert}"])
341
- statsd.gauge('datadog.api.success', 0, :tags => ["alert:#{alert}"])
339
+ unless alert.nil?
340
+ statsd.gauge('datadog.api.unknown_error', 1, tags: ["alert:#{alert}"])
341
+ statsd.gauge('datadog.api.client_error', 0, tags: ["alert:#{alert}"])
342
+ statsd.gauge('datadog.api.success', 0, tags: ["alert:#{alert}"])
342
343
  log.error("unknown error while #{action} alert '#{alert['name']}':" \
343
344
  " query was '#{alert['metric']['datadog_query']}'" \
344
345
  " response was #{resp[0]}:'#{resp[1].inspect}'")
345
346
  end
346
347
  else
347
348
  @stats[:api_successes] += 1
348
- if !alert.nil?
349
- statsd.gauge('datadog.api.unknown_error', 0, :tags => ["alert:#{alert}"])
350
- statsd.gauge('datadog.api.client_error', 0, :tags => ["alert:#{alert}"])
351
- statsd.gauge('datadog.api.success', 1, :tags => ["alert:#{alert}"])
349
+ unless alert.nil?
350
+ statsd.gauge('datadog.api.unknown_error', 0, tags: ["alert:#{alert}"])
351
+ statsd.gauge('datadog.api.client_error', 0, tags: ["alert:#{alert}"])
352
+ statsd.gauge('datadog.api.success', 1, tags: ["alert:#{alert}"])
352
353
  end
353
354
  end
354
355
  end
355
-
356
356
  end
357
357
  end