sensu 0.9.9.beta → 0.9.9.beta.1

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.
data/CHANGELOG.md CHANGED
@@ -8,14 +8,21 @@ via the API (/info).
8
8
  Aggregate results available via the API when using a parameter
9
9
  (?results=true).
10
10
 
11
+ Event filters; filtering events for handlers, using event attribute
12
+ matching.
13
+
11
14
  ### Other
12
15
 
13
16
  Server is now using basic AMQP QoS (prefetch), just enough back pressure.
14
17
 
18
+ Improved check execution scheduling.
19
+
15
20
  Fixed server execute command method error handling.
16
21
 
17
22
  Events with a resolve action bypass handler severity filtering.
18
23
 
24
+ Check flap detection configuration validation.
25
+
19
26
  ## 0.9.8 - 2012-11-15
20
27
 
21
28
  ### Features
data/lib/sensu/api.rb CHANGED
@@ -443,17 +443,25 @@ module Sensu
443
443
  response = Array.new
444
444
  $redis.smembers('aggregates').callback do |checks|
445
445
  unless checks.empty?
446
- checks.each_with_index do |check_name, index|
447
- $redis.smembers('aggregates:' + check_name).callback do |aggregates|
448
- collection = {
449
- :check => check_name,
450
- :issued => aggregates.sort.reverse.take(10)
451
- }
452
- response.push(collection)
453
- if index == checks.size - 1
454
- body response.to_json
446
+ limit = 10
447
+ if params[:limit]
448
+ limit = params[:limit] =~ /^[0-9]+$/ ? params[:limit].to_i : nil
449
+ end
450
+ unless limit.nil?
451
+ checks.each_with_index do |check_name, index|
452
+ $redis.smembers('aggregates:' + check_name).callback do |aggregates|
453
+ collection = {
454
+ :check => check_name,
455
+ :issued => aggregates.sort.reverse.take(limit)
456
+ }
457
+ response.push(collection)
458
+ if index == checks.size - 1
459
+ body response.to_json
460
+ end
455
461
  end
456
462
  end
463
+ else
464
+ bad_request!
457
465
  end
458
466
  else
459
467
  body response.to_json
@@ -463,7 +471,38 @@ module Sensu
463
471
 
464
472
  aget %r{/aggregates/([\w\.-]+)$} do |check_name|
465
473
  $redis.smembers('aggregates:' + check_name).callback do |aggregates|
466
- body aggregates.sort.reverse.take(10).to_json
474
+ unless aggregates.empty?
475
+ limit = 10
476
+ if params[:limit]
477
+ limit = params[:limit] =~ /^[0-9]+$/ ? params[:limit].to_i : nil
478
+ end
479
+ unless limit.nil?
480
+ body aggregates.sort.reverse.take(limit).to_json
481
+ else
482
+ bad_request!
483
+ end
484
+ else
485
+ not_found!
486
+ end
487
+ end
488
+ end
489
+
490
+ adelete %r{/aggregates/([\w\.-]+)$} do |check_name|
491
+ $redis.smembers('aggregates:' + check_name).callback do |aggregates|
492
+ unless aggregates.empty?
493
+ aggregates.each do |check_issued|
494
+ result_set = check_name + ':' + check_issued
495
+ $redis.del('aggregation:' + result_set)
496
+ $redis.del('aggregate:' + result_set)
497
+ end
498
+ $redis.del('aggregates:' + check_name).callback do
499
+ $redis.srem('aggregates', check_name).callback do
500
+ no_content!
501
+ end
502
+ end
503
+ else
504
+ not_found!
505
+ end
467
506
  end
468
507
  end
469
508
 
@@ -1,6 +1,6 @@
1
1
  module Sensu
2
2
  unless defined?(Sensu::VERSION)
3
- VERSION = '0.9.9.beta'
3
+ VERSION = '0.9.9.beta.1'
4
4
  end
5
5
 
6
6
  unless defined?(Sensu::DEFAULT_OPTIONS)
data/lib/sensu/server.rb CHANGED
@@ -136,6 +136,21 @@ module Sensu
136
136
  subdue && subdue_at == (check[:subdue][:at] || 'handler').to_sym
137
137
  end
138
138
 
139
+ def event_filtered?(filter_name, event)
140
+ if @settings.filter_exists?(filter_name)
141
+ filter = @settings[:filters][filter_name]
142
+ matched = hash_values_equal?(filter[:attributes], event)
143
+ filter[:negate] ? matched : !matched
144
+ else
145
+ @logger.error('unknown filter', {
146
+ :filter => {
147
+ :name => filter_name
148
+ }
149
+ })
150
+ false
151
+ end
152
+ end
153
+
139
154
  def derive_handlers(handler_list, nested=false)
140
155
  handler_list.inject(Array.new) do |handlers, handler_name|
141
156
  if @settings.handler_exists?(handler_name)
@@ -167,23 +182,43 @@ module Sensu
167
182
  handlers = derive_handlers(handler_list)
168
183
  event_severity = Sensu::SEVERITIES[event[:check][:status]] || 'unknown'
169
184
  handlers.select do |handler|
170
- if check_subdued?(event[:check], :handler)
171
- @logger.info('check is subdued at handler', {
185
+ if event[:action] == :flapping && !handler[:handle_flapping]
186
+ @logger.info('handler does not handle flapping events', {
172
187
  :event => event,
173
188
  :handler => handler
174
189
  })
175
- false
176
- elsif event[:action] == :resolve
177
- true
178
- elsif handler.has_key?(:severities) && !handler[:severities].include?(event_severity)
179
- @logger.debug('handler does not handle event severity', {
190
+ next
191
+ end
192
+ if check_subdued?(event[:check], :handler)
193
+ @logger.info('check is subdued at handler', {
180
194
  :event => event,
181
195
  :handler => handler
182
196
  })
183
- false
184
- else
185
- true
197
+ next
186
198
  end
199
+ if handler.has_key?(:severities) && !handler[:severities].include?(event_severity)
200
+ unless event[:action] == :resolve
201
+ @logger.debug('handler does not handle event severity', {
202
+ :event => event,
203
+ :handler => handler
204
+ })
205
+ next
206
+ end
207
+ end
208
+ if handler.has_key?(:filters) || handler.has_key?(:filter)
209
+ filter_list = Array(handler[:filters] || handler[:filter])
210
+ filtered = filter_list.any? do |filter_name|
211
+ event_filtered?(filter_name, event)
212
+ end
213
+ if filtered
214
+ @logger.debug('event filtered for handler', {
215
+ :event => event,
216
+ :handler => handler
217
+ })
218
+ next
219
+ end
220
+ end
221
+ true
187
222
  end
188
223
  end
189
224
 
@@ -417,8 +452,8 @@ module Sensu
417
452
  :flapping => is_flapping,
418
453
  :occurrences => event[:occurrences]
419
454
  }.to_json).callback do
420
- unless check[:handle] == false || is_flapping
421
- event[:action] = :create
455
+ unless check[:handle] == false
456
+ event[:action] = is_flapping ? :flapping : :create
422
457
  handle_event(event)
423
458
  end
424
459
  end
@@ -545,7 +580,7 @@ module Sensu
545
580
  checks.each do |check_name|
546
581
  @redis.smembers('aggregates:' + check_name).callback do |aggregates|
547
582
  aggregates.sort!
548
- until aggregates.size <= 10
583
+ until aggregates.size <= 20
549
584
  check_issued = aggregates.shift
550
585
  @redis.srem('aggregates:' + check_name, check_issued).callback do
551
586
  result_set = check_name + ':' + check_issued.to_s
@@ -719,5 +754,19 @@ module Sensu
719
754
  end
720
755
  end
721
756
  end
757
+
758
+ def hash_values_equal?(hash_one, hash_two)
759
+ hash_one.keys.all? do |key|
760
+ if hash_one[key] == hash_two[key]
761
+ true
762
+ else
763
+ if hash_one[key].is_a?(Hash) && hash_two[key].is_a?(Hash)
764
+ hash_values_equal?(hash_one[key], hash_two[key])
765
+ else
766
+ false
767
+ end
768
+ end
769
+ end
770
+ end
722
771
  end
723
772
  end
@@ -5,7 +5,7 @@ module Sensu
5
5
  def initialize
6
6
  @logger = Sensu::Logger.get
7
7
  @settings = Hash.new
8
- [:checks, :handlers, :mutators].each do |key|
8
+ [:checks, :filters, :mutators, :handlers].each do |key|
9
9
  @settings[key] = Hash.new
10
10
  end
11
11
  @indifferent_access = false
@@ -89,7 +89,7 @@ module Sensu
89
89
  ENV['SENSU_CONFIG_FILES'] = @loaded_files.join(':')
90
90
  end
91
91
 
92
- [:checks, :handlers, :mutators].each do |key|
92
+ [:checks, :filters, :mutators, :handlers].each do |key|
93
93
  define_method(key) do
94
94
  @settings[key].map do |name, details|
95
95
  details.merge(:name => name.to_s)
@@ -217,6 +217,27 @@ module Sensu
217
217
  :check => check
218
218
  })
219
219
  end
220
+ check[:handlers].each do |handler_name|
221
+ unless handler_name.is_a?(String)
222
+ invalid('check handlers items must be strings', {
223
+ :check => check
224
+ })
225
+ end
226
+ end
227
+ end
228
+ if check.has_key?(:low_flap_threshold)
229
+ unless check[:low_flap_threshold].is_a?(Integer)
230
+ invalid('flap thresholds must be integers', {
231
+ :check => check
232
+ })
233
+ end
234
+ end
235
+ if check.has_key?(:high_flap_threshold)
236
+ unless check[:high_flap_threshold].is_a?(Integer)
237
+ invalid('flap thresholds must be integers', {
238
+ :check => check
239
+ })
240
+ end
220
241
  end
221
242
  if check.has_key?(:subdue)
222
243
  unless check[:subdue].is_a?(Hash)
@@ -315,6 +336,33 @@ module Sensu
315
336
  end
316
337
 
317
338
  def validate_server
339
+ unless @settings[:filters].is_a?(Hash)
340
+ invalid('filters must be a hash')
341
+ end
342
+ filters.each do |filter|
343
+ unless filter[:attributes].is_a?(Hash)
344
+ invalid('filter attributes must be a hash', {
345
+ :filter => filter
346
+ })
347
+ end
348
+ if filter.has_key?(:negate)
349
+ unless !!filter[:negate] == filter[:negate]
350
+ invalid('filter negate must be boolean', {
351
+ :filter => filter
352
+ })
353
+ end
354
+ end
355
+ end
356
+ unless @settings[:mutators].is_a?(Hash)
357
+ invalid('mutators must be a hash')
358
+ end
359
+ mutators.each do |mutator|
360
+ unless mutator[:command].is_a?(String)
361
+ invalid('mutator is missing command', {
362
+ :mutator => mutator
363
+ })
364
+ end
365
+ end
318
366
  unless @settings[:handlers].is_a?(Hash)
319
367
  invalid('handlers must be a hash')
320
368
  end
@@ -327,20 +375,6 @@ module Sensu
327
375
  :handler => handler
328
376
  })
329
377
  end
330
- if handler.has_key?(:severities)
331
- unless handler[:severities].is_a?(Array) && !handler[:severities].empty?
332
- invalid('handler severities must be an array and not empty', {
333
- :handler => handler
334
- })
335
- end
336
- handler[:severities].each do |severity|
337
- unless Sensu::SEVERITIES.include?(severity)
338
- invalid('handler severities are invalid', {
339
- :handler => handler
340
- })
341
- end
342
- end
343
- end
344
378
  case handler[:type]
345
379
  when 'pipe'
346
380
  unless handler[:command].is_a?(String)
@@ -383,14 +417,14 @@ module Sensu
383
417
  end
384
418
  end
385
419
  when 'set'
386
- unless handler[:handlers].is_a?(Array) && handler[:handlers].count > 0
387
- invalid('handler set is missing handlers', {
420
+ unless handler[:handlers].is_a?(Array)
421
+ invalid('handler set handlers must be an array', {
388
422
  :handler => handler
389
423
  })
390
424
  end
391
425
  handler[:handlers].each do |handler_name|
392
426
  unless handler_name.is_a?(String)
393
- invalid('handler set handlers must be strings', {
427
+ invalid('handler set handlers items must be strings', {
394
428
  :handler => handler
395
429
  })
396
430
  end
@@ -400,15 +434,54 @@ module Sensu
400
434
  :handler => handler
401
435
  })
402
436
  end
403
- end
404
- unless @settings[:mutators].is_a?(Hash)
405
- invalid('mutators must be a hash')
406
- end
407
- mutators.each do |mutator|
408
- unless mutator[:command].is_a?(String)
409
- invalid('mutator is missing command', {
410
- :mutator => mutator
411
- })
437
+ if handler.has_key?(:filter)
438
+ unless handler[:filter].is_a?(String)
439
+ invalid('handler filter must be a string', {
440
+ :handler => handler
441
+ })
442
+ end
443
+ end
444
+ if handler.has_key?(:filters)
445
+ unless handler[:filters].is_a?(Array)
446
+ invalid('handler filters must be an array', {
447
+ :handler => handler
448
+ })
449
+ end
450
+ handler[:filters].each do |filter_name|
451
+ unless filter_name.is_a?(String)
452
+ invalid('handler filters items must be strings', {
453
+ :handler => handler
454
+ })
455
+ end
456
+ end
457
+ end
458
+ if handler.has_key?(:mutator)
459
+ unless handler[:mutator].is_a?(String)
460
+ invalid('handler mutator must be a string', {
461
+ :handler => handler
462
+ })
463
+ end
464
+ end
465
+ if handler.has_key?(:handle_flapping)
466
+ unless !!handler[:handle_flapping] == handler[:handle_flapping]
467
+ invalid('handler handle_flapping must be boolean', {
468
+ :handler => handler
469
+ })
470
+ end
471
+ end
472
+ if handler.has_key?(:severities)
473
+ unless handler[:severities].is_a?(Array) && !handler[:severities].empty?
474
+ invalid('handler severities must be an array and not empty', {
475
+ :handler => handler
476
+ })
477
+ end
478
+ handler[:severities].each do |severity|
479
+ unless Sensu::SEVERITIES.include?(severity)
480
+ invalid('handler severities are invalid', {
481
+ :handler => handler
482
+ })
483
+ end
484
+ end
412
485
  end
413
486
  end
414
487
  end
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sensu
3
3
  version: !ruby/object:Gem::Version
4
- hash: -1732117756
4
+ hash: 1653984923
5
5
  prerelease: true
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
9
  - 9
10
10
  - beta
11
- version: 0.9.9.beta
11
+ - 1
12
+ version: 0.9.9.beta.1
12
13
  platform: ruby
13
14
  authors:
14
15
  - Sean Porter
@@ -17,7 +18,7 @@ autorequire:
17
18
  bindir: bin
18
19
  cert_chain: []
19
20
 
20
- date: 2012-11-27 00:00:00 -08:00
21
+ date: 2012-12-06 00:00:00 -08:00
21
22
  default_executable:
22
23
  dependencies:
23
24
  - !ruby/object:Gem::Dependency