interferon 0.1.0 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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