flapjack 0.8.9 → 0.8.10

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 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