sensu 0.9.12 → 0.9.13.beta

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
@@ -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] =~ /^[0-9]+$/ ? params[:limit].to_i : 0
142
- offset = params[:offset] =~ /^[0-9]+$/ ? params[:offset].to_i : 0
143
- unless limit == 0
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
- valid_request = true
496
- if params[:age]
497
- if params[:age] =~ /^[0-9]+$/
498
- timestamp = Time.now.to_i - params[:age].to_i
499
- aggregates.reject! do |issued|
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
- if valid_request
507
- aggregates = pagination(aggregates.sort.reverse)
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
@@ -1,6 +1,6 @@
1
1
  module Sensu
2
2
  unless defined?(Sensu::VERSION)
3
- VERSION = '0.9.12'
3
+ VERSION = '0.9.13.beta'
4
4
 
5
5
  LOG_LEVELS = [:debug, :info, :warn, :error, :fatal]
6
6
 
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
- process_result(result)
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.info('publishing check result', {
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 >= 180
595
- check[:output] = 'No keep-alive sent from client in over 180 seconds'
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 >= 120
598
- check[:output] = 'No keep-alive sent from client in over 120 seconds'
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 120 seconds ago'
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)
@@ -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: 35
5
- prerelease: false
4
+ hash: -799367686
5
+ prerelease: true
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- - 12
10
- version: 0.9.12
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-03 00:00:00 -07:00
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: 3
239
+ hash: 25
239
240
  segments:
240
- - 0
241
- version: "0"
241
+ - 1
242
+ - 3
243
+ - 1
244
+ version: 1.3.1
242
245
  requirements: []
243
246
 
244
247
  rubyforge_project: