flapjack 0.8.9 → 0.8.10

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: ac75cd5f3cf88878ef41b54de2a1d4ca3007387e
4
- data.tar.gz: 941ba78adea49cfa2025c5b848d7debf070d37b5
3
+ metadata.gz: de195d7c1f069b7e1817c654b51315c55df5ec37
4
+ data.tar.gz: b6f8b5059820e001df53e1a7f3ef6fdbd49c90cb
5
5
  SHA512:
6
- metadata.gz: d55e5a48109d8eb7733dd45e854ac590b2f069fd6011aeb2017bbe0fbad66feacd41a460c5945bf42953f4afd3486f0be82c5155a3fce2f3ecb3d661c05919b8
7
- data.tar.gz: 20666c66b76ef55c0105c1929a86073979280e11b91b31ac9498720bbb751dac3bd72fac3dba1bba747673275bb9bde1cb0f2b417f00f8a4eeed5348ac202505
6
+ metadata.gz: e0131f314a1c13869035a9ec07cbca94bd8a79b56af800b7183291e50fade89bccd023223ccf2b7037d0c8bab9fc20ca25aec348e0e0ca8baf371071f530ad47
7
+ data.tar.gz: 9710ad57f6ced3f0b4f276690dce38e5accd4361613ef3944811893d7faa46c5871e92e07da2cd30428d7a85cfc2b3d7887067c9b1f068565fc577410c7538c6
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ## Flapjack Changelog
2
2
 
3
+ # 0.8.10 - 2014-04-28
4
+ - Feature: Add regex entities to notification rules #463 (@jswoods)
5
+ - Bug: oobetet gateway exception sending pagerduty event #464 (@jessereynolds)
6
+ - Bug: Event counters don't add up #465 (@jessereynolds)
7
+
3
8
  # 0.8.9 - 2014-04-21
4
9
  - Feature: Support arbitrary gateways in notifier, queue names from config gh-456 (@auxesis)
5
10
  - Feature: Add chat bot features (ack by regex, query status by regex) gh-459 (@someword)
@@ -246,6 +246,7 @@ module Flapjack
246
246
  if rules.all? {|r| r.is_specific? } # also true if empty
247
247
  rule = self.add_notification_rule({
248
248
  :entities => [],
249
+ :regex_entities => [],
249
250
  :tags => Flapjack::Data::TagSet.new([]),
250
251
  :regex_tags => Flapjack::Data::TagSet.new([]),
251
252
  :time_restrictions => [],
@@ -261,7 +261,7 @@ module Flapjack
261
261
  end
262
262
 
263
263
  def failure?
264
- ['critical', 'warning', 'unknown'].include?(state)
264
+ ['critical', 'warning', 'unknown', 'down', 'unreachable'].include?(state)
265
265
  end
266
266
 
267
267
  # # Not used anywhere
@@ -143,16 +143,19 @@ module Flapjack
143
143
  # matchers are rules of the contact that have matched the current event
144
144
  # for time, entity and tags
145
145
  matchers = rules.select do |rule|
146
- logger.debug("considering rule with entities: #{rule.entities}, tags: #{rule.tags.to_json} and regex tags: #{rule.regex_tags.to_json}")
147
- rule_has_tags = rule.tags ? (rule.tags.length > 0) : false
148
- rule_has_regex_tags = rule.regex_tags ? (rule.regex_tags.length > 0) : false
149
- rule_has_entities = rule.entities ? (rule.entities.length > 0) : false
150
-
151
- matches_tags = rule_has_tags ? rule.match_tags?(@tags) : true
152
- matches_regex_tags = rule_has_regex_tags ? rule.match_regex_tags?(@tags) : true
153
- matches_entity = rule_has_entities ? rule.match_entity?(@event_id) : true
154
-
155
- ((matches_entity && matches_tags && matches_regex_tags) || ! rule.is_specific?) &&
146
+ logger.debug("considering rule with entities: #{rule.entities}, entities regex: #{rule.regex_entities},
147
+ tags: #{rule.tags.to_json} and regex tags: #{rule.regex_tags.to_json}")
148
+ rule_has_tags = rule.tags ? (rule.tags.length > 0) : false
149
+ rule_has_regex_tags = rule.regex_tags ? (rule.regex_tags.length > 0) : false
150
+ rule_has_entities = rule.entities ? (rule.entities.length > 0) : false
151
+ rule_has_regex_entities = rule.regex_entities ? (rule.regex_entities.length > 0) : false
152
+
153
+ matches_tags = rule_has_tags ? rule.match_tags?(@tags) : true
154
+ matches_regex_tags = rule_has_regex_tags ? rule.match_regex_tags?(@tags) : true
155
+ matches_entity = rule_has_entities ? rule.match_entity?(@event_id) : true
156
+ matches_regex_entities = rule_has_regex_entities ? rule.match_regex_entities?(@event_id) : true
157
+
158
+ ((matches_entity && matches_regex_entities && matches_tags && matches_regex_tags) || ! rule.is_specific?) &&
156
159
  rule_occurring_now?(rule, :contact => contact, :default_timezone => default_timezone)
157
160
  end
158
161
 
@@ -12,7 +12,7 @@ module Flapjack
12
12
 
13
13
  extend Flapjack::Utility
14
14
 
15
- attr_accessor :id, :contact_id, :entities, :tags, :regex_tags,
15
+ attr_accessor :id, :contact_id, :entities, :regex_entities, :tags, :regex_tags,
16
16
  :time_restrictions, :unknown_media, :warning_media, :critical_media,
17
17
  :unknown_blackhole, :warning_blackhole, :critical_blackhole
18
18
 
@@ -74,7 +74,7 @@ module Flapjack
74
74
  end
75
75
 
76
76
  def to_json(*args)
77
- self.class.hashify(:id, :contact_id, :tags, :regex_tags, :entities,
77
+ self.class.hashify(:id, :contact_id, :tags, :regex_tags, :entities, :regex_entities,
78
78
  :time_restrictions, :unknown_media, :warning_media, :critical_media,
79
79
  :unknown_blackhole, :warning_blackhole, :critical_blackhole) {|k|
80
80
  [k, self.send(k)]
@@ -87,6 +87,17 @@ module Flapjack
87
87
  @entities.include?(event_id.split(':').first)
88
88
  end
89
89
 
90
+ # entity names match regex?
91
+ def match_regex_entities?(event_id)
92
+ return false unless @regex_entities && @regex_entities.length > 0
93
+ entity = event_id.split(':').first
94
+ matches = 0
95
+ @regex_entities.each do |regex_entity|
96
+ matches += 1 if /#{regex_entity}/ === entity
97
+ end
98
+ matches >= @regex_entities.length
99
+ end
100
+
90
101
  # tags match?
91
102
  def match_tags?(event_tags)
92
103
  return false unless @tags && @tags.length > 0
@@ -124,6 +135,7 @@ module Flapjack
124
135
 
125
136
  def is_specific?
126
137
  (!@entities.nil? && !@entities.empty?) ||
138
+ (!@regex_entities.nil? && !@regex_entities.empty?) ||
127
139
  (!@tags.nil? && !@tags.empty?) ||
128
140
  (!@regex_tags.nil? && !@regex_tags.empty?)
129
141
  end
@@ -172,6 +184,7 @@ module Flapjack
172
184
  :id => rule_data[:id].to_s,
173
185
  :contact_id => rule_data[:contact_id].to_s,
174
186
  :entities => Oj.dump(rule_data[:entities]),
187
+ :regex_entities => Oj.dump(rule_data[:regex_entities]),
175
188
  :tags => Oj.dump(tag_data),
176
189
  :regex_tags => Oj.dump(regex_tag_data),
177
190
  :time_restrictions => Oj.dump(rule_data[:time_restrictions], :mode => :compat),
@@ -262,6 +275,12 @@ module Flapjack
262
275
  d[:entities].all? {|e| e.is_a?(String)} ) } =>
263
276
  "entities must be a list of strings",
264
277
 
278
+ proc {|d| !d.has_key?(:regex_entities) ||
279
+ ( d[:regex_entities].nil? ||
280
+ d[:regex_entities].is_a?(Array) &&
281
+ d[:regex_entities].all? {|e| e.is_a?(String)} ) } =>
282
+ "regex_entities must be a list of strings",
283
+
265
284
  proc {|d| !d.has_key?(:tags) ||
266
285
  ( d[:tags].nil? ||
267
286
  d[:tags].is_a?(Flapjack::Data::TagSet) &&
@@ -345,6 +364,7 @@ module Flapjack
345
364
  regex_tags = Oj.load(rule_data['regex_tags'] || '')
346
365
  @regex_tags = regex_tags ? Flapjack::Data::TagSet.new(regex_tags) : nil
347
366
  @entities = Oj.load(rule_data['entities'] || '')
367
+ @regex_entities = Oj.load(rule_data['regex_entities'] || '')
348
368
  @time_restrictions = Oj.load(rule_data['time_restrictions'] || '')
349
369
  @unknown_media = Oj.load(rule_data['unknown_media'] || '')
350
370
  @warning_media = Oj.load(rule_data['warning_media'] || '')
@@ -144,7 +144,7 @@ module Flapjack
144
144
 
145
145
  contact = find_contact(params[:contact_id])
146
146
 
147
- rule_data = hashify(:entities, :tags, :regex_tags,
147
+ rule_data = hashify(:entities, :regex_entities, :tags, :regex_tags,
148
148
  :unknown_media, :warning_media, :critical_media, :time_restrictions,
149
149
  :unknown_blackhole, :warning_blackhole, :critical_blackhole) {|k| [k, params[k]]}
150
150
 
@@ -167,7 +167,7 @@ module Flapjack
167
167
  rule = find_rule(params[:id])
168
168
  contact = find_contact(rule.contact_id)
169
169
 
170
- rule_data = hashify(:entities, :tags, :regex_tags,
170
+ rule_data = hashify(:entities, :regex_entities, :tags, :regex_tags,
171
171
  :unknown_media, :warning_media, :critical_media, :time_restrictions,
172
172
  :unknown_blackhole, :warning_blackhole, :critical_blackhole) {|k| [k, params[k]]}
173
173
 
@@ -190,10 +190,10 @@ module Flapjack
190
190
 
191
191
  def emit_pagerduty(summary, event_type = 'trigger')
192
192
  if @config['pagerduty_contact']
193
- pagerduty_event = { :service_key => @config['pagerduty_contact'],
194
- :incident_key => "Flapjack Self Monitoring from #{@hostname}",
195
- :event_type => event_type,
196
- :description => summary }
193
+ pagerduty_event = { 'service_key' => @config['pagerduty_contact'],
194
+ 'incident_key' => "Flapjack Self Monitoring from #{@hostname}",
195
+ 'event_type' => event_type,
196
+ 'description' => summary }
197
197
  status, response = send_pagerduty_event(pagerduty_event)
198
198
  if status == 200
199
199
  @logger.debug("successfully sent pagerduty event")
@@ -211,7 +211,7 @@ module Flapjack
211
211
 
212
212
  def send_pagerduty_event(event)
213
213
  options = { :body => Oj.dump(event) }
214
- http = EM::HttpRequest.new(@pagerduty_events_api_url).post(options)
214
+ http = EM::HttpRequest.new(@pagerduty_events_api_url).post(options)
215
215
  response = Oj.load(http.response)
216
216
  status = http.response_header.status
217
217
  @logger.debug "send_pagerduty_event got a return code of #{status.to_s} - #{response.inspect}"
@@ -102,8 +102,9 @@
102
102
  <tr>
103
103
  <th>ID</th>
104
104
  <th>Entities</th>
105
+ <th>Entities Regex</th>
105
106
  <th>Tags</th>
106
- <th>Regex Tags</th>
107
+ <th>Tags Regex</th>
107
108
  <th>Warning Media</th>
108
109
  <th>Critical Media</th>
109
110
  <th>Time Restrictions</th>
@@ -113,6 +114,7 @@
113
114
  <tr>
114
115
  <td><%= h rule.id %></td>
115
116
  <td><%= h( (rule.entities && !rule.entities.empty?) ? rule.entities.join(', ') : '-') %></td>
117
+ <td><%= h( (rule.regex_entities && !rule.regex_entities.empty?) ? rule.regex_entities.join(', ') : '-') %></td>
116
118
  <td><%= h( (rule.tags && !rule.tags.empty?) ? rule.tags.to_a.join(', ') : '-') %></td>
117
119
  <td><%= h( (rule.regex_tags && !rule.regex_tags.empty?) ? rule.regex_tags.to_a.join(', ') : '-') %></td>
118
120
  <td><%= h( (rule.warning_media && !rule.warning_media.empty?) ? rule.warning_media.join(', ') : '-')%></td>
@@ -36,6 +36,7 @@
36
36
  <li>ok: <%= h @event_counters['ok'] %> events</li>
37
37
  <li>failure: <%= h @event_counters['failure'] %> events</li>
38
38
  <li>action: <%= h @event_counters['action'] %> events</li>
39
+ <li>invalid: <%= h @event_counters['invalid'] %> events</li>
39
40
  </ul>
40
41
  </td>
41
42
  </tr>
@@ -86,6 +87,7 @@
86
87
  <li>ok: <%= h event_counters['ok'] %> (<%= h event_rates['ok'] %> events/s)</li>
87
88
  <li>failure: <%= h event_counters['failure'] %> (<%= h event_rates['failure'] %> events/s)</li>
88
89
  <li>action: <%= h event_counters['action'] %> (<%= h event_rates['action'] %> events/s)</li>
90
+ <li>invalid: <%= h event_counters['invalid'] %> (<%= h event_rates['invalid'] %> events/s)</li>
89
91
  </ul>
90
92
  </td>
91
93
  </tr>
@@ -95,7 +97,7 @@
95
97
  </div>
96
98
 
97
99
  <p>
98
- <a class="btn btn-success" href="/self_stats.json">View as JSON</a>.
100
+ <a class="btn btn-success" href="/self_stats.json">View as JSON</a>
99
101
  Learn how to
100
102
  <a href="https://github.com/flpjck/flapjack/wiki/Gathering-internal-statistics-with-collectd">
101
103
  use these metrics</a>.
@@ -58,18 +58,19 @@ module Flapjack
58
58
  # point on...
59
59
 
60
60
  # FIXME: add an administrative function to reset all event counters
61
- if @redis.hget('event_counters', 'all').nil?
62
- @redis.hset('event_counters', 'all', 0)
63
- @redis.hset('event_counters', 'ok', 0)
64
- @redis.hset('event_counters', 'failure', 0)
65
- @redis.hset('event_counters', 'action', 0)
66
- end
67
-
61
+
62
+ @redis.hset('event_counters', 'all', 0) if @redis.hget('event_counters', 'all').nil?
63
+ @redis.hset('event_counters', 'ok', 0) if @redis.hget('event_counters', 'ok').nil?
64
+ @redis.hset('event_counters', 'failure', 0) if @redis.hget('event_counters', 'failure').nil?
65
+ @redis.hset('event_counters', 'action', 0) if @redis.hget('event_counters', 'action').nil?
66
+ @redis.hset('event_counters', 'invalid', 0) if @redis.hget('event_counters', 'invalid').nil?
67
+
68
68
  @redis.hset("executive_instance:#{@instance_id}", 'boot_time', boot_time.to_i)
69
69
  @redis.hset("event_counters:#{@instance_id}", 'all', 0)
70
70
  @redis.hset("event_counters:#{@instance_id}", 'ok', 0)
71
71
  @redis.hset("event_counters:#{@instance_id}", 'failure', 0)
72
72
  @redis.hset("event_counters:#{@instance_id}", 'action', 0)
73
+ @redis.hset("event_counters:#{@instance_id}", 'invalid', 0)
73
74
  touch_keys
74
75
  end
75
76
 
@@ -105,7 +106,14 @@ module Flapjack
105
106
  break
106
107
  end
107
108
 
108
- process_event(event) unless event.nil?
109
+ if event.nil?
110
+ @redis.hincrby('event_counters', 'all', 1)
111
+ @redis.hincrby("event_counters:#{@instance_id}", 'all', 1)
112
+ @redis.hincrby('event_counters', 'invalid', 1)
113
+ @redis.hincrby("event_counters:#{@instance_id}", 'invalid', 1)
114
+ else
115
+ process_event(event)
116
+ end
109
117
  end
110
118
 
111
119
  @logger.info("Exiting main loop.")
@@ -166,7 +174,7 @@ module Flapjack
166
174
 
167
175
  event.counter = @redis.hincrby('event_counters', 'all', 1)
168
176
  @redis.hincrby("event_counters:#{@instance_id}", 'all', 1)
169
-
177
+
170
178
  # FIXME skip if entity_check.nil?
171
179
 
172
180
  # FIXME: validate that the event is sane before we ever get here
@@ -188,6 +196,10 @@ module Flapjack
188
196
  elsif event.failure?
189
197
  @redis.hincrby('event_counters', 'failure', 1)
190
198
  @redis.hincrby("event_counters:#{@instance_id}", 'failure', 1)
199
+ else
200
+ @redis.hincrby('event_counters', 'invalid', 1)
201
+ @redis.hincrby("event_counters:#{@instance_id}", 'invalid', 1)
202
+ @logger.error("Invalid event received: #{event.inspect}")
191
203
  end
192
204
  @redis.exec
193
205
 
@@ -223,6 +235,10 @@ module Flapjack
223
235
  @redis.hincrby('event_counters', 'action', 1)
224
236
  @redis.hincrby("event_counters:#{@instance_id}", 'action', 1)
225
237
  @redis.exec
238
+ else
239
+ @redis.hincrby('event_counters', 'invalid', 1)
240
+ @redis.hincrby("event_counters:#{@instance_id}", 'invalid', 1)
241
+ @logger.error("Invalid event received: #{event.inspect}")
226
242
  end
227
243
 
228
244
  [result, previous_state]
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  module Flapjack
4
- VERSION = "0.8.9"
4
+ VERSION = "0.8.10"
5
5
  end
6
6
 
@@ -17,6 +17,7 @@ describe Flapjack::Data::NotificationRule, :redis => true do
17
17
  :tags => ["database","physical"],
18
18
  :regex_tags => [],
19
19
  :entities => ["foo-app-01.example.com"],
20
+ :regex_entities => [],
20
21
  :time_restrictions => [ weekdays_8_18 ],
21
22
  :unknown_media => [],
22
23
  :warning_media => ["email"],
@@ -31,7 +32,8 @@ describe Flapjack::Data::NotificationRule, :redis => true do
31
32
  {:contact_id => '23',
32
33
  :tags => [],
33
34
  :regex_tags => ["^data.*$","^(physical|bare_metal)$"],
34
- :entities => ["foo-app-01.example.com"],
35
+ :entities => [],
36
+ :regex_entities => ["^foo-\S{3}-\d{2}.example.com$"],
35
37
  :time_restrictions => [ weekdays_8_18 ],
36
38
  :unknown_media => [],
37
39
  :warning_media => ["email"],
@@ -44,6 +44,7 @@ describe 'Flapjack::Gateways::API::ContactMethods', :sinatra => true, :logger =>
44
44
  "tags" => ["database","physical"],
45
45
  "regex_tags" => ["^data.*$","^(physical|bare_metal)$"],
46
46
  "entities" => ["foo-app-01.example.com"],
47
+ "regex_entities" => ["^foo-\S{3}-\d{2}.example.com$"],
47
48
  "time_restrictions" => nil,
48
49
  "unknown_media" => ["jabber"],
49
50
  "warning_media" => ["email"],
@@ -45,7 +45,7 @@ describe 'Flapjack::Gateways::JSONAPI::ContactMethods', :sinatra => true, :logge
45
45
  {"contact_id" => "21",
46
46
  "tags" => ["database","physical"],
47
47
  "regex_tags" => ["^data.*$","^(physical|bare_metal)$"],
48
- "entities" => ["foo-app-01.example.com"],
48
+ "regex_entities" => ["^foo-\S{3}-\d{2}.example.com$"],
49
49
  "time_restrictions" => nil,
50
50
  "unknown_media" => ["jabber"],
51
51
  "warning_media" => ["email"],
@@ -24,14 +24,20 @@ describe Flapjack::Processor, :logger => true do
24
24
  expect(redis).to receive(:hset).with(/^executive_instance:/, "boot_time", anything)
25
25
  expect(redis).to receive(:hget).with('event_counters', 'all').and_return(nil)
26
26
  expect(redis).to receive(:hset).with('event_counters', 'all', 0)
27
+ expect(redis).to receive(:hget).with('event_counters', 'ok').and_return(nil)
27
28
  expect(redis).to receive(:hset).with('event_counters', 'ok', 0)
29
+ expect(redis).to receive(:hget).with('event_counters', 'failure').and_return(nil)
28
30
  expect(redis).to receive(:hset).with('event_counters', 'failure', 0)
31
+ expect(redis).to receive(:hget).with('event_counters', 'action').and_return(nil)
29
32
  expect(redis).to receive(:hset).with('event_counters', 'action', 0)
33
+ expect(redis).to receive(:hget).with('event_counters', 'invalid').and_return(nil)
34
+ expect(redis).to receive(:hset).with('event_counters', 'invalid', 0)
30
35
 
31
36
  expect(redis).to receive(:hset).with(/^event_counters:/, 'all', 0)
32
37
  expect(redis).to receive(:hset).with(/^event_counters:/, 'ok', 0)
33
38
  expect(redis).to receive(:hset).with(/^event_counters:/, 'failure', 0)
34
39
  expect(redis).to receive(:hset).with(/^event_counters:/, 'action', 0)
40
+ expect(redis).to receive(:hset).with(/^event_counters:/, 'invalid', 0)
35
41
 
36
42
  expect(redis).to receive(:expire).with(/^executive_instance:/, anything)
37
43
  expect(redis).to receive(:expire).with(/^event_counters:/, anything).exactly(4).times
@@ -3,27 +3,29 @@
3
3
  require 'redis'
4
4
 
5
5
  require 'oj'
6
- Oj.default_options = { :indent => 0, :mode => :strict }
6
+ Oj.default_options = { :indent => 0, :mode => :compat }
7
7
 
8
8
  id = "%.2d" % (1..10).to_a[rand(9)]
9
9
 
10
10
  events = []
11
11
 
12
- events << {
12
+ events << Oj.dump({
13
13
  'entity' => "app-#{id}",
14
14
  'check' => 'http',
15
15
  'type' => 'service',
16
16
  'state' => 'ok',
17
- }.to_json
17
+ 'summary' => 'well i don\'t know',
18
+ })
18
19
 
19
- events << {
20
+ events << Oj.dump({
20
21
  'entity' => "app-#{id}",
21
22
  'check' => 'http',
22
- 'type' => 'service',
23
+ 'type' => 'host',
23
24
  'state' => 'critical',
24
- }.to_json
25
+ 'summary' => 'well i don\'t know',
26
+ })
25
27
 
26
- redis = Redis.new
28
+ redis = Redis.new(:db => 13)
27
29
 
28
30
  2000.times do
29
31
  events.each {|event|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flapjack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.9
4
+ version: 0.8.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lindsay Holmwood
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-03-21 00:00:00.000000000 Z
13
+ date: 2014-03-28 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: dante