sensu 0.9.9.beta → 0.9.9.beta.1

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