sensu 0.9.12 → 0.9.13.beta
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +9 -0
- data/lib/sensu/api.rb +45 -18
- data/lib/sensu/constants.rb +1 -1
- data/lib/sensu/server.rb +38 -7
- data/lib/sensu/settings.rb +35 -0
- metadata +12 -9
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## 0.9.13 - TBD
|
2
|
+
|
3
|
+
### Features
|
4
|
+
|
5
|
+
The Sensu API now provides /health, an endpoint for connection & queue
|
6
|
+
monitoring. Monitor Sensu health with services like Pingdom.
|
7
|
+
|
8
|
+
Sensu clients can configure their own keepalive handler(s) and thresholds.
|
9
|
+
|
1
10
|
## 0.9.12 - 2013-04-03
|
2
11
|
|
3
12
|
### Features
|
data/lib/sensu/api.rb
CHANGED
@@ -137,10 +137,14 @@ module Sensu
|
|
137
137
|
env['rack.input'].rewind
|
138
138
|
end
|
139
139
|
|
140
|
+
def integer_parameter(parameter)
|
141
|
+
parameter =~ /^[0-9]+$/ ? parameter.to_i : nil
|
142
|
+
end
|
143
|
+
|
140
144
|
def pagination(items)
|
141
|
-
limit = params[:limit]
|
142
|
-
offset = params[:offset]
|
143
|
-
unless limit
|
145
|
+
limit = integer_parameter(params[:limit])
|
146
|
+
offset = integer_parameter(params[:offset]) || 0
|
147
|
+
unless limit.nil?
|
144
148
|
headers['X-Pagination'] = Oj.dump(
|
145
149
|
:limit => limit,
|
146
150
|
:offset => offset,
|
@@ -161,6 +165,10 @@ module Sensu
|
|
161
165
|
ahalt 404
|
162
166
|
end
|
163
167
|
|
168
|
+
def unavailable!
|
169
|
+
ahalt 503
|
170
|
+
end
|
171
|
+
|
164
172
|
def created!(response)
|
165
173
|
status 201
|
166
174
|
body response
|
@@ -246,6 +254,33 @@ module Sensu
|
|
246
254
|
end
|
247
255
|
end
|
248
256
|
|
257
|
+
aget '/health' do
|
258
|
+
if $redis.connected? && $rabbitmq.connected?
|
259
|
+
healthy = Array.new
|
260
|
+
min_consumers = integer_parameter(params[:consumers])
|
261
|
+
max_messages = integer_parameter(params[:messages])
|
262
|
+
$amq.queue('keepalives').status do |messages, consumers|
|
263
|
+
if min_consumers
|
264
|
+
healthy << (consumers >= min_consumers)
|
265
|
+
end
|
266
|
+
if max_messages
|
267
|
+
healthy << (messages <= max_messages)
|
268
|
+
end
|
269
|
+
$amq.queue('results').status do |messages, consumers|
|
270
|
+
if min_consumers
|
271
|
+
healthy << (consumers >= min_consumers)
|
272
|
+
end
|
273
|
+
if max_messages
|
274
|
+
healthy << (messages <= max_messages)
|
275
|
+
end
|
276
|
+
healthy.all? ? no_content! : unavailable!
|
277
|
+
end
|
278
|
+
end
|
279
|
+
else
|
280
|
+
unavailable!
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
249
284
|
aget '/clients' do
|
250
285
|
response = Array.new
|
251
286
|
$redis.smembers('clients') do |clients|
|
@@ -492,23 +527,15 @@ module Sensu
|
|
492
527
|
aggregates.map! do |issued|
|
493
528
|
issued.to_i
|
494
529
|
end
|
495
|
-
|
496
|
-
if
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
issued > timestamp
|
501
|
-
end
|
502
|
-
else
|
503
|
-
valid_request = false
|
530
|
+
age = integer_parameter(params[:age])
|
531
|
+
if age
|
532
|
+
timestamp = Time.now.to_i - age
|
533
|
+
aggregates.reject! do |issued|
|
534
|
+
issued > timestamp
|
504
535
|
end
|
505
536
|
end
|
506
|
-
|
507
|
-
|
508
|
-
body Oj.dump(aggregates)
|
509
|
-
else
|
510
|
-
bad_request!
|
511
|
-
end
|
537
|
+
aggregates = pagination(aggregates.sort.reverse)
|
538
|
+
body Oj.dump(aggregates)
|
512
539
|
else
|
513
540
|
not_found!
|
514
541
|
end
|
data/lib/sensu/constants.rb
CHANGED
data/lib/sensu/server.rb
CHANGED
@@ -502,6 +502,16 @@ module Sensu
|
|
502
502
|
end
|
503
503
|
end
|
504
504
|
|
505
|
+
def valid_result?(result)
|
506
|
+
if result[:client].is_a?(String) && result[:check].is_a?(Hash)
|
507
|
+
result[:check][:name].is_a?(String) &&
|
508
|
+
result[:check][:output].is_a?(String) &&
|
509
|
+
result[:check][:status].is_a?(Integer)
|
510
|
+
else
|
511
|
+
false
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
505
515
|
def setup_results
|
506
516
|
@logger.debug('subscribing to results')
|
507
517
|
@result_queue = @amq.queue!('results')
|
@@ -511,7 +521,13 @@ module Sensu
|
|
511
521
|
@logger.debug('received result', {
|
512
522
|
:result => result
|
513
523
|
})
|
514
|
-
|
524
|
+
if valid_result?(result)
|
525
|
+
process_result(result)
|
526
|
+
else
|
527
|
+
@logger.warn('invalid result', {
|
528
|
+
:result => result
|
529
|
+
})
|
530
|
+
end
|
515
531
|
EM::next_tick do
|
516
532
|
header.ack
|
517
533
|
end
|
@@ -572,7 +588,7 @@ module Sensu
|
|
572
588
|
:client => client[:name],
|
573
589
|
:check => check
|
574
590
|
}
|
575
|
-
@logger.
|
591
|
+
@logger.debug('publishing check result', {
|
576
592
|
:payload => payload
|
577
593
|
})
|
578
594
|
@amq.direct('results').publish(Oj.dump(payload))
|
@@ -589,16 +605,31 @@ module Sensu
|
|
589
605
|
:issued => Time.now.to_i,
|
590
606
|
:executed => Time.now.to_i
|
591
607
|
}
|
608
|
+
thresholds = {
|
609
|
+
:warning => 120,
|
610
|
+
:critical => 180
|
611
|
+
}
|
612
|
+
if client.has_key?(:keepalive)
|
613
|
+
if client[:keepalive].has_key?(:handler) || client[:keepalive].has_key?(:handlers)
|
614
|
+
check[:handlers] = Array(client[:keepalive][:handlers] || client[:keepalive][:handler])
|
615
|
+
end
|
616
|
+
if client[:keepalive].has_key?(:thresholds)
|
617
|
+
thresholds.merge!(client[:keepalive][:thresholds])
|
618
|
+
end
|
619
|
+
end
|
592
620
|
time_since_last_keepalive = Time.now.to_i - client[:timestamp]
|
593
621
|
case
|
594
|
-
when time_since_last_keepalive >=
|
595
|
-
check[:output] = 'No keep-alive sent from client in over
|
622
|
+
when time_since_last_keepalive >= thresholds[:critical]
|
623
|
+
check[:output] = 'No keep-alive sent from client in over '
|
624
|
+
check[:output] << thresholds[:critical].to_s + ' seconds'
|
596
625
|
check[:status] = 2
|
597
|
-
when time_since_last_keepalive >=
|
598
|
-
check[:output] = 'No keep-alive sent from client in over
|
626
|
+
when time_since_last_keepalive >= thresholds[:warning]
|
627
|
+
check[:output] = 'No keep-alive sent from client in over '
|
628
|
+
check[:output] << thresholds[:warning].to_s + ' seconds'
|
599
629
|
check[:status] = 1
|
600
630
|
else
|
601
|
-
check[:output] = 'Keep-alive sent from client less than
|
631
|
+
check[:output] = 'Keep-alive sent from client less than '
|
632
|
+
check[:output] << thresholds[:warning].to_s + ' seconds ago'
|
602
633
|
check[:status] = 0
|
603
634
|
end
|
604
635
|
publish_result(client, check)
|
data/lib/sensu/settings.rb
CHANGED
@@ -390,6 +390,41 @@ module Sensu
|
|
390
390
|
invalid('client subscriptions must each be a string')
|
391
391
|
end
|
392
392
|
end
|
393
|
+
if @settings[:client].has_key?(:keepalive)
|
394
|
+
unless @settings[:client][:keepalive].is_a?(Hash)
|
395
|
+
invalid('client keepalive must be a hash')
|
396
|
+
end
|
397
|
+
if @settings[:client][:keepalive].has_key?(:handler)
|
398
|
+
unless @settings[:client][:keepalive][:handler].is_a?(String)
|
399
|
+
invalid('client keepalive handler must be a string')
|
400
|
+
end
|
401
|
+
end
|
402
|
+
if @settings[:client][:keepalive].has_key?(:handlers)
|
403
|
+
handlers = @settings[:client][:keepalive][:handlers]
|
404
|
+
unless handlers.is_a?(Array)
|
405
|
+
invalid('client keepalive handlers must be an array')
|
406
|
+
end
|
407
|
+
handlers.each do |handler_name|
|
408
|
+
unless handler_name.is_a?(String)
|
409
|
+
invalid('client keepalive handlers must each be a string')
|
410
|
+
end
|
411
|
+
end
|
412
|
+
end
|
413
|
+
if @settings[:client][:keepalive].has_key?(:thresholds)
|
414
|
+
thresholds = @settings[:client][:keepalive][:thresholds]
|
415
|
+
unless thresholds.is_a?(Hash)
|
416
|
+
invalid('client keepalive thresholds must be a hash')
|
417
|
+
end
|
418
|
+
if thresholds.has_key?(:warning) || thresholds.has_key?(:critical)
|
419
|
+
unless thresholds[:warning].is_a?(Integer)
|
420
|
+
invalid('client keepalive warning threshold must be an integer')
|
421
|
+
end
|
422
|
+
unless thresholds[:critical].is_a?(Integer)
|
423
|
+
invalid('client keepalive critical threshold must be an integer')
|
424
|
+
end
|
425
|
+
end
|
426
|
+
end
|
427
|
+
end
|
393
428
|
end
|
394
429
|
|
395
430
|
def validate_api
|
metadata
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sensu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: -799367686
|
5
|
+
prerelease: true
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 9
|
9
|
-
-
|
10
|
-
|
9
|
+
- 13
|
10
|
+
- beta
|
11
|
+
version: 0.9.13.beta
|
11
12
|
platform: ruby
|
12
13
|
authors:
|
13
14
|
- Sean Porter
|
@@ -16,7 +17,7 @@ autorequire:
|
|
16
17
|
bindir: bin
|
17
18
|
cert_chain: []
|
18
19
|
|
19
|
-
date: 2013-04-
|
20
|
+
date: 2013-04-19 00:00:00 -07:00
|
20
21
|
default_executable:
|
21
22
|
dependencies:
|
22
23
|
- !ruby/object:Gem::Dependency
|
@@ -233,12 +234,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
233
234
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
234
235
|
none: false
|
235
236
|
requirements:
|
236
|
-
- - "
|
237
|
+
- - ">"
|
237
238
|
- !ruby/object:Gem::Version
|
238
|
-
hash:
|
239
|
+
hash: 25
|
239
240
|
segments:
|
240
|
-
-
|
241
|
-
|
241
|
+
- 1
|
242
|
+
- 3
|
243
|
+
- 1
|
244
|
+
version: 1.3.1
|
242
245
|
requirements: []
|
243
246
|
|
244
247
|
rubyforge_project:
|