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 +7 -0
- data/lib/sensu/api.rb +49 -10
- data/lib/sensu/constants.rb +1 -1
- data/lib/sensu/server.rb +62 -13
- data/lib/sensu/settings.rb +101 -28
- metadata +4 -3
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
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
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
|
-
|
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
|
|
data/lib/sensu/constants.rb
CHANGED
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
|
171
|
-
@logger.info('
|
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
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
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
|
-
|
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
|
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 <=
|
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
|
data/lib/sensu/settings.rb
CHANGED
@@ -5,7 +5,7 @@ module Sensu
|
|
5
5
|
def initialize
|
6
6
|
@logger = Sensu::Logger.get
|
7
7
|
@settings = Hash.new
|
8
|
-
[:checks, :
|
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, :
|
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)
|
387
|
-
invalid('handler set
|
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
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
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:
|
4
|
+
hash: 1653984923
|
5
5
|
prerelease: true
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 9
|
9
9
|
- 9
|
10
10
|
- beta
|
11
|
-
|
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-
|
21
|
+
date: 2012-12-06 00:00:00 -08:00
|
21
22
|
default_executable:
|
22
23
|
dependencies:
|
23
24
|
- !ruby/object:Gem::Dependency
|