sensu 0.9.6.beta.4 → 0.9.6.beta.5

Sign up to get free protection for your applications and to get access to all the features.
data/lib/sensu/api.rb CHANGED
@@ -1,10 +1,8 @@
1
1
  require File.join(File.dirname(__FILE__), 'base')
2
+ require File.join(File.dirname(__FILE__), 'redis')
2
3
 
3
4
  require 'thin'
4
5
  require 'sinatra/async'
5
- require 'redis'
6
-
7
- require File.join(File.dirname(__FILE__), 'patches', 'redis')
8
6
 
9
7
  module Sensu
10
8
  class API < Sinatra::Base
@@ -26,13 +24,17 @@ module Sensu
26
24
  end
27
25
 
28
26
  def self.setup(options={})
27
+ $logger = Cabin::Channel.get
29
28
  base = Sensu::Base.new(options)
30
- $logger = base.logger
31
29
  $settings = base.settings
32
30
  $logger.debug('connecting to redis', {
33
31
  :settings => $settings[:redis]
34
32
  })
35
- $redis = Redis.connect($settings[:redis])
33
+ $redis = Sensu::Redis.connect($settings[:redis])
34
+ $redis.on_disconnect = Proc.new do
35
+ $logger.warn('reconnecting to redis')
36
+ $redis.reconnect!
37
+ end
36
38
  $logger.debug('connecting to rabbitmq', {
37
39
  :settings => $settings[:rabbitmq]
38
40
  })
@@ -45,7 +47,15 @@ module Sensu
45
47
  end
46
48
  end
47
49
 
48
- def request_log(env)
50
+ def healthy?
51
+ unless $redis.connected?
52
+ unless env['REQUEST_PATH'] == '/info'
53
+ halt 500
54
+ end
55
+ end
56
+ end
57
+
58
+ def request_log
49
59
  $logger.info([env['REQUEST_METHOD'], env['REQUEST_PATH']].join(' '), {
50
60
  :remote_address => env['REMOTE_ADDR'],
51
61
  :user_agent => env['HTTP_USER_AGENT'],
@@ -71,7 +81,8 @@ module Sensu
71
81
 
72
82
  before do
73
83
  content_type 'application/json'
74
- request_log(env)
84
+ request_log
85
+ healthy?
75
86
  end
76
87
 
77
88
  aget '/info' do
@@ -80,16 +91,10 @@ module Sensu
80
91
  :version => Sensu::VERSION
81
92
  },
82
93
  :health => {
83
- :redis => 'ok',
84
- :rabbitmq => 'ok'
94
+ :redis => $redis.connected? ? 'ok' : 'down',
95
+ :rabbitmq => $rabbitmq.connected? ? 'ok' : 'down'
85
96
  }
86
97
  }
87
- if $redis.reconnecting?
88
- response[:health][:redis] = 'down'
89
- end
90
- if $rabbitmq.reconnecting?
91
- response[:health][:rabbitmq] = 'down'
92
- end
93
98
  body response.to_json
94
99
  end
95
100
 
@@ -378,10 +383,9 @@ module Sensu
378
383
  :signal => signal
379
384
  })
380
385
  $logger.warn('stopping')
386
+ $redis.close
381
387
  $logger.warn('stopping reactor')
382
- EM::PeriodicTimer.new(0.25) do
383
- EM::stop_event_loop
384
- end
388
+ EM::stop_event_loop
385
389
  end
386
390
  end
387
391
  end
data/lib/sensu/base.rb CHANGED
@@ -10,7 +10,6 @@ require 'cabin'
10
10
  require 'amqp'
11
11
 
12
12
  require File.join(File.dirname(__FILE__), 'patches', 'ruby')
13
- require File.join(File.dirname(__FILE__), 'patches', 'amqp')
14
13
 
15
14
  require File.join(File.dirname(__FILE__), 'constants')
16
15
  require File.join(File.dirname(__FILE__), 'cli')
@@ -20,11 +19,10 @@ require File.join(File.dirname(__FILE__), 'process')
20
19
 
21
20
  module Sensu
22
21
  class Base
23
- attr_reader :options, :logger, :settings
22
+ attr_reader :options, :settings
24
23
 
25
24
  def initialize(options={})
26
25
  @options = Sensu::DEFAULT_OPTIONS.merge(options)
27
- @logger = Cabin::Channel.get
28
26
  setup_logging
29
27
  setup_settings
30
28
  setup_process
@@ -43,15 +41,7 @@ module Sensu
43
41
  Dir[@options[:config_dir] + '/**/*.json'].each do |file|
44
42
  @settings.load_file(file)
45
43
  end
46
- begin
47
- @settings.validate
48
- rescue => error
49
- @logger.fatal('config invalid', {
50
- :error => error.to_s
51
- })
52
- @logger.fatal('SENSU NOT RUNNING!')
53
- exit 2
54
- end
44
+ @settings.validate
55
45
  @settings.set_env
56
46
  end
57
47
 
data/lib/sensu/client.rb CHANGED
@@ -22,8 +22,8 @@ module Sensu
22
22
  end
23
23
 
24
24
  def initialize(options={})
25
+ @logger = Cabin::Channel.get
25
26
  base = Sensu::Base.new(options)
26
- @logger = base.logger
27
27
  @settings = base.settings
28
28
  @timers = Array.new
29
29
  @checks_in_progress = Array.new
@@ -48,8 +48,8 @@ module Sensu
48
48
  def setup_keepalives
49
49
  @logger.debug('scheduling keepalives')
50
50
  publish_keepalive
51
- @timers << EM::PeriodicTimer.new(30) do
52
- unless @rabbitmq.reconnecting?
51
+ @timers << EM::PeriodicTimer.new(20) do
52
+ if @rabbitmq.connected?
53
53
  publish_keepalive
54
54
  end
55
55
  end
@@ -90,7 +90,8 @@ module Sensu
90
90
  substitute
91
91
  end
92
92
  if unmatched_tokens.empty?
93
- execute = proc do
93
+ execute = Proc.new do
94
+ check = check.dup
94
95
  started = Time.now.to_f
95
96
  begin
96
97
  IO.popen(command + ' 2>&1') do |io|
@@ -105,14 +106,11 @@ module Sensu
105
106
  check[:status] = 2
106
107
  end
107
108
  check[:duration] = ('%.3f' % (Time.now.to_f - started)).to_f
109
+ check
108
110
  end
109
- publish = proc do
111
+ publish = Proc.new do |check|
110
112
  unless check[:status].nil?
111
113
  publish_result(check)
112
- else
113
- @logger.warn('nil exit status code', {
114
- :check => check
115
- })
116
114
  end
117
115
  @checks_in_progress.delete(check[:name])
118
116
  end
@@ -178,28 +176,28 @@ module Sensu
178
176
  def setup_rabbitmq_monitor
179
177
  @logger.debug('monitoring rabbitmq connection')
180
178
  @timers << EM::PeriodicTimer.new(5) do
181
- if @rabbitmq.reconnecting?
182
- @logger.warn('reconnecting to rabbitmq')
183
- else
179
+ if @rabbitmq.connected?
184
180
  unless @check_request_queue.subscribed?
185
181
  @logger.warn('re-subscribing to client subscriptions')
186
182
  setup_subscriptions
187
183
  end
184
+ else
185
+ @logger.warn('reconnecting to rabbitmq')
188
186
  end
189
187
  end
190
188
  end
191
189
 
192
- def setup_standalone(options={})
190
+ def setup_standalone
193
191
  @logger.debug('scheduling standalone checks')
194
192
  standalone_check_count = 0
195
- stagger = options[:test] ? 0 : 7
193
+ stagger = testing? ? 0 : 7
196
194
  @settings.checks.each do |check|
197
195
  if check[:standalone]
198
196
  standalone_check_count += 1
199
197
  @timers << EM::Timer.new(stagger * standalone_check_count) do
200
- interval = options[:test] ? 0.5 : check[:interval]
198
+ interval = testing? ? 0.5 : check[:interval]
201
199
  @timers << EM::PeriodicTimer.new(interval) do
202
- unless @rabbitmq.reconnecting?
200
+ if @rabbitmq.connected?
203
201
  check[:issued] = Time.now.to_i
204
202
  execute_check(check)
205
203
  end
@@ -226,19 +224,33 @@ module Sensu
226
224
  end
227
225
  end
228
226
 
229
- def stop_reactor
227
+ def unsubscribe(&block)
228
+ if @rabbitmq.connected?
229
+ @logger.warn('unsubscribing from client subscriptions')
230
+ @check_request_queue.unsubscribe do
231
+ if block
232
+ block.call
233
+ end
234
+ end
235
+ else
236
+ if block
237
+ block.call
238
+ end
239
+ end
240
+ end
241
+
242
+ def complete_checks_in_progress(&block)
230
243
  @logger.info('completing checks in progress', {
231
244
  :checks_in_progress => @checks_in_progress
232
245
  })
233
- complete_in_progress = EM::tick_loop do
246
+ complete = EM::tick_loop do
234
247
  if @checks_in_progress.empty?
235
248
  :stop
236
249
  end
237
250
  end
238
- complete_in_progress.on_stop do
239
- @logger.warn('stopping reactor')
240
- EM::PeriodicTimer.new(0.25) do
241
- EM::stop_event_loop
251
+ complete.on_stop do
252
+ if block
253
+ block.call
242
254
  end
243
255
  end
244
256
  end
@@ -251,14 +263,18 @@ module Sensu
251
263
  @timers.each do |timer|
252
264
  timer.cancel
253
265
  end
254
- unless @rabbitmq.reconnecting?
255
- @logger.warn('unsubscribing from client subscriptions')
256
- @check_request_queue.unsubscribe do
257
- stop_reactor
266
+ unsubscribe do
267
+ complete_checks_in_progress do
268
+ @logger.warn('stopping reactor')
269
+ EM::stop_event_loop
258
270
  end
259
- else
260
- EM::stop_event_loop
261
271
  end
262
272
  end
273
+
274
+ private
275
+
276
+ def testing?
277
+ File.basename($0) == 'rake'
278
+ end
263
279
  end
264
280
  end
@@ -1,6 +1,6 @@
1
1
  module Sensu
2
2
  unless defined?(Sensu::VERSION)
3
- VERSION = '0.9.6.beta.4'
3
+ VERSION = '0.9.6.beta.5'
4
4
  end
5
5
 
6
6
  unless defined?(Sensu::DEFAULT_OPTIONS)
@@ -0,0 +1,81 @@
1
+ require 'redis'
2
+
3
+ module Sensu
4
+ class Redis < Redis::Client
5
+ attr_accessor :host, :port, :password, :on_disconnect
6
+
7
+ def initialize(*args)
8
+ super
9
+ @logger = Cabin::Channel.get
10
+ @connected = false
11
+ @closing_connection = false
12
+ end
13
+
14
+ def connection_completed
15
+ @connected = true
16
+ if @password
17
+ auth(@password).callback do |reply|
18
+ unless reply == 'OK'
19
+ @logger.fatal('redis authentication failed')
20
+ close_connection
21
+ end
22
+ end
23
+ end
24
+ info.callback do |reply|
25
+ redis_version = reply.split(/\n/).first.split(/:/).last.chomp
26
+ if redis_version < '1.3.14'
27
+ @logger.fatal('redis version must be >= 2.0 RC 1')
28
+ close_connection
29
+ end
30
+ end
31
+ end
32
+
33
+ def reconnect!
34
+ EM::Timer.new(1) do
35
+ reconnect(@host, @port)
36
+ end
37
+ end
38
+
39
+ def close
40
+ @closing_connection = true
41
+ close_connection
42
+ end
43
+
44
+ def unbind
45
+ @connected = false
46
+ super
47
+ if @on_disconnect && !@closing_connection
48
+ @on_disconnect.call
49
+ end
50
+ end
51
+
52
+ def connected?
53
+ @connected
54
+ end
55
+
56
+ def self.connect(options)
57
+ options ||= Hash.new
58
+ if options.is_a?(String)
59
+ begin
60
+ uri = URI.parse(options)
61
+ host = uri.host
62
+ port = uri.port || 6379
63
+ password = uri.password
64
+ rescue
65
+ @logger.fatal('invalid redis url')
66
+ @logger.fatal('SENSU NOT RUNNING!')
67
+ exit 2
68
+ end
69
+ else
70
+ host = options[:host] || 'localhost'
71
+ port = options[:port] || 6379
72
+ password = options[:password]
73
+ end
74
+ EM::connect(host, port, self) do |redis|
75
+ redis.host = host
76
+ redis.port = port
77
+ redis.password = password
78
+ end
79
+ end
80
+ end
81
+ end
data/lib/sensu/server.rb CHANGED
@@ -1,8 +1,5 @@
1
1
  require File.join(File.dirname(__FILE__), 'base')
2
-
3
- require 'redis'
4
-
5
- require File.join(File.dirname(__FILE__), 'patches', 'redis')
2
+ require File.join(File.dirname(__FILE__), 'redis')
6
3
 
7
4
  module Sensu
8
5
  class Server
@@ -27,8 +24,8 @@ module Sensu
27
24
  end
28
25
 
29
26
  def initialize(options={})
27
+ @logger = Cabin::Channel.get
30
28
  base = Sensu::Base.new(options)
31
- @logger = base.logger
32
29
  @settings = base.settings
33
30
  @timers = Array.new
34
31
  @handlers_in_progress = 0
@@ -38,7 +35,13 @@ module Sensu
38
35
  @logger.debug('connecting to redis', {
39
36
  :settings => @settings[:redis]
40
37
  })
41
- @redis = Redis.connect(@settings[:redis])
38
+ @redis = Sensu::Redis.connect(@settings[:redis])
39
+ unless testing?
40
+ @redis.on_disconnect = Proc.new do
41
+ @logger.fatal('redis connection closed')
42
+ stop('TERM')
43
+ end
44
+ end
42
45
  end
43
46
 
44
47
  def setup_rabbitmq
@@ -63,7 +66,7 @@ module Sensu
63
66
  end
64
67
  end
65
68
 
66
- def check_subdued?(check, subdue_type)
69
+ def check_subdued?(check, subdue_at)
67
70
  subdue = false
68
71
  if check[:subdue].is_a?(Hash)
69
72
  if check[:subdue].has_key?(:start) && check[:subdue].has_key?(:end)
@@ -93,8 +96,8 @@ module Sensu
93
96
  end
94
97
  end
95
98
  if subdue
96
- (!check[:subdue].has_key?(:at) && subdue_type == :handler) ||
97
- (check[:subdue].has_key?(:at) && check[:subdue][:at].to_sym == subdue_type)
99
+ (!check[:subdue].has_key?(:at) && subdue_at == :handler) ||
100
+ (check[:subdue].has_key?(:at) && check[:subdue][:at].to_sym == subdue_at)
98
101
  else
99
102
  false
100
103
  end
@@ -109,11 +112,8 @@ module Sensu
109
112
  else
110
113
  ['default']
111
114
  end
112
- handler_list.reject! do |handler_name|
113
- !@settings.handler_exists?(handler_name)
114
- end
115
115
  handler_list.map! do |handler_name|
116
- if @settings[:handlers][handler_name][:type] == 'set'
116
+ if @settings.handler_exists?(handler_name) && @settings[:handlers][handler_name][:type] == 'set'
117
117
  @settings[:handlers][handler_name][:handlers]
118
118
  else
119
119
  handler_name
@@ -122,7 +122,16 @@ module Sensu
122
122
  handler_list.flatten!
123
123
  handler_list.uniq!
124
124
  handler_list.reject! do |handler_name|
125
- !@settings.handler_exists?(handler_name)
125
+ unless @settings.handler_exists?(handler_name)
126
+ @logger.warn('unknown handler', {
127
+ :handler => {
128
+ :name => handler_name
129
+ }
130
+ })
131
+ true
132
+ else
133
+ false
134
+ end
126
135
  end
127
136
  handler_list.map do |handler_name|
128
137
  @settings[:handlers][handler_name].merge(:name => handler_name)
@@ -131,31 +140,23 @@ module Sensu
131
140
 
132
141
  def handle_event(event)
133
142
  unless check_subdued?(event[:check], :handler)
134
- report = proc do |output|
135
- if output.is_a?(String)
136
- output.split(/\n+/).each do |line|
137
- @logger.info('handler output', {
138
- :output => line
139
- })
140
- end
141
- end
142
- @handlers_in_progress -= 1
143
- end
144
143
  handlers = check_handlers(event[:check])
145
144
  handlers.each do |handler|
146
- @logger.debug('handling event', {
145
+ @logger.info('handling event', {
147
146
  :event => event,
148
147
  :handler => handler
149
148
  })
150
149
  @handlers_in_progress += 1
151
150
  case handler[:type]
152
151
  when 'pipe'
153
- execute = proc do
152
+ execute = Proc.new do
154
153
  begin
155
154
  IO.popen(handler[:command] + ' 2>&1', 'r+') do |io|
156
155
  io.write(event.to_json)
157
156
  io.close_write
158
- io.read
157
+ io.read.split(/\n+/).each do |line|
158
+ @logger.debug(line)
159
+ end
159
160
  end
160
161
  rescue Errno::ENOENT => error
161
162
  @logger.error('handler does not exist', {
@@ -177,7 +178,10 @@ module Sensu
177
178
  })
178
179
  end
179
180
  end
180
- EM::defer(execute, report)
181
+ complete = Proc.new do
182
+ @handlers_in_progress -= 1
183
+ end
184
+ EM::defer(execute, complete)
181
185
  when 'amqp'
182
186
  exchange_name = handler[:exchange][:name]
183
187
  exchange_type = handler[:exchange].has_key?(:type) ? handler[:exchange][:type].to_sym : :direct
@@ -324,18 +328,18 @@ module Sensu
324
328
  end
325
329
  end
326
330
 
327
- def setup_publisher(options={})
331
+ def setup_publisher
328
332
  @logger.debug('scheduling check requests')
329
333
  check_count = 0
330
- stagger = options[:test] ? 0 : 7
334
+ stagger = testing? ? 0 : 7
331
335
  @settings.checks.each do |check|
332
336
  unless check[:publish] == false || check[:standalone]
333
337
  check_count += 1
334
338
  @timers << EM::Timer.new(stagger * check_count) do
335
- interval = options[:test] ? 0.5 : check[:interval]
339
+ interval = testing? ? 0.5 : check[:interval]
336
340
  @timers << EM::PeriodicTimer.new(interval) do
337
341
  unless check_subdued?(check, :publisher)
338
- unless @rabbitmq.reconnecting?
342
+ if @rabbitmq.connected?
339
343
  payload = {
340
344
  :name => check[:name],
341
345
  :issued => Time.now.to_i
@@ -369,7 +373,7 @@ module Sensu
369
373
  def setup_keepalive_monitor
370
374
  @logger.debug('monitoring client keepalives')
371
375
  @timers << EM::PeriodicTimer.new(30) do
372
- unless @rabbitmq.reconnecting?
376
+ if @rabbitmq.connected?
373
377
  @logger.debug('checking for stale client info')
374
378
  @redis.smembers('clients').callback do |clients|
375
379
  clients.each do |client_name|
@@ -382,17 +386,17 @@ module Sensu
382
386
  time_since_last_keepalive = Time.now.to_i - client[:timestamp]
383
387
  case
384
388
  when time_since_last_keepalive >= 180
385
- check[:output] = 'No keep-alive sent from host in over 180 seconds'
389
+ check[:output] = 'No keep-alive sent from client in over 180 seconds'
386
390
  check[:status] = 2
387
391
  publish_result(client, check)
388
392
  when time_since_last_keepalive >= 120
389
- check[:output] = 'No keep-alive sent from host in over 120 seconds'
393
+ check[:output] = 'No keep-alive sent from client in over 120 seconds'
390
394
  check[:status] = 1
391
395
  publish_result(client, check)
392
396
  else
393
397
  @redis.hexists('events:' + client[:name], 'keepalive').callback do |exists|
394
398
  if exists
395
- check[:output] = 'Keep-alive sent from host'
399
+ check[:output] = 'Keep-alive sent from client'
396
400
  check[:status] = 0
397
401
  publish_result(client, check)
398
402
  end
@@ -434,7 +438,7 @@ module Sensu
434
438
  end
435
439
 
436
440
  def resign_as_master(&block)
437
- if @is_master
441
+ if @redis.connected? && @is_master
438
442
  @redis.del('lock:master').callback do
439
443
  @logger.warn('resigned as master')
440
444
  if block
@@ -442,7 +446,6 @@ module Sensu
442
446
  end
443
447
  end
444
448
  else
445
- @logger.warn('not currently master')
446
449
  if block
447
450
  block.call
448
451
  end
@@ -465,9 +468,7 @@ module Sensu
465
468
  def setup_rabbitmq_monitor
466
469
  @logger.debug('monitoring rabbitmq connection')
467
470
  @timers << EM::PeriodicTimer.new(5) do
468
- if @rabbitmq.reconnecting?
469
- @logger.warn('reconnecting to rabbitmq')
470
- else
471
+ if @rabbitmq.connected?
471
472
  unless @keepalive_queue.subscribed?
472
473
  @logger.warn('re-subscribing to keepalives')
473
474
  setup_keepalives
@@ -476,23 +477,42 @@ module Sensu
476
477
  @logger.warn('re-subscribing to results')
477
478
  setup_results
478
479
  end
480
+ else
481
+ @logger.warn('reconnecting to rabbitmq')
482
+ end
483
+ end
484
+ end
485
+
486
+ def unsubscribe(&block)
487
+ if @rabbitmq.connected?
488
+ @logger.warn('unsubscribing from keepalives')
489
+ @keepalive_queue.unsubscribe do
490
+ @logger.warn('unsubscribing from results')
491
+ @result_queue.unsubscribe do
492
+ if block
493
+ block.call
494
+ end
495
+ end
496
+ end
497
+ else
498
+ if block
499
+ block.call
479
500
  end
480
501
  end
481
502
  end
482
503
 
483
- def stop_reactor
504
+ def complete_handlers_in_progress(&block)
484
505
  @logger.info('completing handlers in progress', {
485
506
  :handlers_in_progress => @handlers_in_progress
486
507
  })
487
- complete_in_progress = EM::tick_loop do
508
+ complete = EM::tick_loop do
488
509
  if @handlers_in_progress == 0
489
510
  :stop
490
511
  end
491
512
  end
492
- complete_in_progress.on_stop do
493
- @logger.warn('stopping reactor')
494
- EM::PeriodicTimer.new(0.25) do
495
- EM::stop_event_loop
513
+ complete.on_stop do
514
+ if block
515
+ block.call
496
516
  end
497
517
  end
498
518
  end
@@ -505,21 +525,21 @@ module Sensu
505
525
  @timers.each do |timer|
506
526
  timer.cancel
507
527
  end
508
- unless @rabbitmq.reconnecting?
509
- @logger.warn('unsubscribing from keepalives')
510
- @keepalive_queue.unsubscribe do
511
- @logger.warn('unsubscribing from results')
512
- @result_queue.unsubscribe do
513
- resign_as_master do
514
- stop_reactor
515
- end
516
- end
517
- end
518
- else
528
+ unsubscribe do
519
529
  resign_as_master do
520
- stop_reactor
530
+ complete_handlers_in_progress do
531
+ @redis.close
532
+ @logger.warn('stopping reactor')
533
+ EM::stop_event_loop
534
+ end
521
535
  end
522
536
  end
523
537
  end
538
+
539
+ private
540
+
541
+ def testing?
542
+ File.basename($0) == 'rake'
543
+ end
524
544
  end
525
545
  end
@@ -172,74 +172,108 @@ module Sensu
172
172
  end
173
173
  end
174
174
 
175
+ def invalid(reason, details={})
176
+ @logger.fatal('invalid settings', {
177
+ :reason => reason
178
+ }.merge(details))
179
+ @logger.fatal('SENSU NOT RUNNING!')
180
+ exit 2
181
+ end
182
+
175
183
  def validate_checks
176
184
  unless @settings[:checks].is_a?(Hash)
177
- raise('missing check configuration')
185
+ invalid('missing checks configuration')
178
186
  end
179
187
  checks.each do |check|
180
188
  unless check[:interval].is_a?(Integer) && check[:interval] > 0
181
- raise('missing interval for check: ' + check[:name])
189
+ invalid('check is missing interval', {
190
+ :check => check
191
+ })
182
192
  end
183
193
  unless check[:command].is_a?(String)
184
- raise('missing command for check: ' + check[:name])
194
+ invalid('check is missing command', {
195
+ :check => check
196
+ })
185
197
  end
186
198
  unless check[:standalone]
187
199
  unless check[:subscribers].is_a?(Array) && check[:subscribers].count > 0
188
- raise('missing subscribers for check: ' + check[:name])
200
+ invalid('check is missing subscribers', {
201
+ :check => check
202
+ })
189
203
  end
190
204
  check[:subscribers].each do |subscriber|
191
205
  unless subscriber.is_a?(String) && !subscriber.empty?
192
- raise('a check subscriber must be a string for check: ' + check[:name])
206
+ invalid('check subscribers must each be a string', {
207
+ :check => check
208
+ })
193
209
  end
194
210
  end
195
211
  end
196
212
  if check.has_key?(:handler)
197
213
  unless check[:handler].is_a?(String)
198
- raise('handler must be a string for check: ' + check[:name])
214
+ invalid('check handler must be a string', {
215
+ :check => check
216
+ })
199
217
  end
200
218
  end
201
219
  if check.has_key?(:handlers)
202
220
  unless check[:handlers].is_a?(Array)
203
- raise('handlers must be an array for check: ' + check[:name])
221
+ invalid('check handlers must be an array', {
222
+ :check => check
223
+ })
204
224
  end
205
225
  end
206
226
  if check.has_key?(:subdue)
207
227
  unless check[:subdue].is_a?(Hash)
208
- raise('subdue must be a hash for check: ' + check[:name])
228
+ invalid('check subdue must be a hash', {
229
+ :check => check
230
+ })
209
231
  end
210
232
  if check[:subdue].has_key?(:start) || check[:subdue].has_key?(:end)
211
233
  begin
212
234
  Time.parse(check[:subdue][:start])
213
235
  Time.parse(check[:subdue][:end])
214
236
  rescue
215
- raise('subdue start & end times must be valid for check: ' + check[:name])
237
+ invalid('check subdue start & end times must be valid', {
238
+ :check => check
239
+ })
216
240
  end
217
241
  end
218
242
  if check[:subdue].has_key?(:days)
219
243
  unless check[:subdue][:days].is_a?(Array)
220
- raise('subdue days must be an array for check: ' + check[:name])
244
+ invalid('check subdue days must be an array', {
245
+ :check => check
246
+ })
221
247
  end
222
248
  check[:subdue][:days].each do |day|
223
249
  days = %w[sunday monday tuesday wednesday thursday friday saturday]
224
250
  unless day.is_a?(String) && days.include?(day.downcase)
225
- raise('subdue days must be valid days of the week for check: ' + check[:name])
251
+ invalid('check subdue days must be valid days of the week', {
252
+ :check => check
253
+ })
226
254
  end
227
255
  end
228
256
  end
229
257
  if check[:subdue].has_key?(:exceptions)
230
258
  unless check[:subdue][:exceptions].is_a?(Array)
231
- raise('subdue exceptions must be an array for check: ' + check[:name])
259
+ invalid('check subdue exceptions must be an array', {
260
+ :check => check
261
+ })
232
262
  end
233
263
  check[:subdue][:exceptions].each do |exception|
234
264
  unless exception.is_a?(Hash)
235
- raise('subdue exception items must be a hash for check: ' + check[:name])
265
+ invalid('check subdue exceptions must each be a hash', {
266
+ :check => check
267
+ })
236
268
  end
237
269
  if exception.has_key?(:start) || exception.has_key?(:end)
238
270
  begin
239
271
  Time.parse(exception[:start])
240
272
  Time.parse(exception[:end])
241
273
  rescue
242
- raise('subdue exception start & end times must be valid for check: ' + check[:name])
274
+ invalid('check subdue exception start & end times must be valid', {
275
+ :check => check
276
+ })
243
277
  end
244
278
  end
245
279
  end
@@ -250,75 +284,89 @@ module Sensu
250
284
 
251
285
  def validate_client
252
286
  unless @settings[:client].is_a?(Hash)
253
- raise('missing client configuration')
287
+ invalid('missing client configuration')
254
288
  end
255
289
  unless @settings[:client][:name].is_a?(String)
256
- raise('client must have a name')
290
+ invalid('client must have a name')
257
291
  end
258
292
  unless @settings[:client][:address].is_a?(String)
259
- raise('client must have an address')
293
+ invalid('client must have an address')
260
294
  end
261
295
  unless @settings[:client][:subscriptions].is_a?(Array) && @settings[:client][:subscriptions].count > 0
262
- raise('client must have subscriptions')
296
+ invalid('client must have subscriptions')
263
297
  end
264
298
  @settings[:client][:subscriptions].each do |subscription|
265
299
  unless subscription.is_a?(String) && !subscription.empty?
266
- raise('a client subscription must be a string')
300
+ invalid('client subscriptions must each be a string')
267
301
  end
268
302
  end
269
303
  end
270
304
 
271
305
  def validate_api
272
306
  unless @settings[:api].is_a?(Hash)
273
- raise('missing api configuration')
307
+ invalid('missing api configuration')
274
308
  end
275
309
  unless @settings[:api][:port].is_a?(Integer)
276
- raise('api port must be an integer')
310
+ invalid('api port must be an integer')
277
311
  end
278
312
  if @settings[:api].has_key?(:user) || @settings[:api].has_key?(:password)
279
313
  unless @settings[:api][:user].is_a?(String)
280
- raise('api user must be a string')
314
+ invalid('api user must be a string')
281
315
  end
282
316
  unless @settings[:api][:password].is_a?(String)
283
- raise('api password must be a string')
317
+ invalid('api password must be a string')
284
318
  end
285
319
  end
286
320
  end
287
321
 
288
322
  def validate_server
289
323
  unless @settings[:handlers].is_a?(Hash)
290
- raise('missing handler configuration')
324
+ invalid('missing handlers configuration')
291
325
  end
292
326
  unless @settings[:handlers].include?(:default)
293
- raise('missing default handler')
327
+ invalid('missing default handler')
294
328
  end
295
329
  handlers.each do |handler|
296
330
  unless handler[:type].is_a?(String)
297
- raise('missing type for handler: ' + handler[:name])
331
+ invalid('handler is missing type', {
332
+ :handler => handler
333
+ })
298
334
  end
299
335
  case handler[:type]
300
336
  when 'pipe'
301
337
  unless handler[:command].is_a?(String)
302
- raise('missing command for pipe handler: ' + handler[:name])
338
+ invalid('handler is missing command', {
339
+ :handler => handler
340
+ })
303
341
  end
304
342
  when 'amqp'
305
343
  unless handler[:exchange].is_a?(Hash)
306
- raise('missing exchange details for amqp handler: ' + handler[:name])
344
+ invalid('handler is missing exchange hash', {
345
+ :handler => handler
346
+ })
307
347
  end
308
348
  unless handler[:exchange][:name].is_a?(String)
309
- raise('missing exchange name for amqp handler: ' + handler[:name])
349
+ invalid('handler is missing exchange name', {
350
+ :handler => handler
351
+ })
310
352
  end
311
353
  if handler[:exchange].has_key?(:type)
312
354
  unless %w[direct fanout topic].include?(handler[:exchange][:type])
313
- raise('invalid exchange type for amqp handler: ' + handler[:name])
355
+ invalid('handler exchange type is invalid', {
356
+ :handler => handler
357
+ })
314
358
  end
315
359
  end
316
360
  when 'set'
317
361
  unless handler[:handlers].is_a?(Array) && handler[:handlers].count > 0
318
- raise('missing handler set for handler: ' + handler[:name])
362
+ invalid('handler set is missing handlers', {
363
+ :handler => handler
364
+ })
319
365
  end
320
366
  else
321
- raise('unknown type for handler: ' + handler[:name])
367
+ invalid('unknown handler type', {
368
+ :handler => handler
369
+ })
322
370
  end
323
371
  end
324
372
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sensu
3
3
  version: !ruby/object:Gem::Version
4
- hash: 62196235
4
+ hash: 62196233
5
5
  prerelease: true
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
9
  - 6
10
10
  - beta
11
- - 4
12
- version: 0.9.6.beta.4
11
+ - 5
12
+ version: 0.9.6.beta.5
13
13
  platform: ruby
14
14
  authors:
15
15
  - Sean Porter
@@ -18,7 +18,7 @@ autorequire:
18
18
  bindir: bin
19
19
  cert_chain: []
20
20
 
21
- date: 2012-05-19 00:00:00 -07:00
21
+ date: 2012-05-25 00:00:00 -07:00
22
22
  default_executable:
23
23
  dependencies:
24
24
  - !ruby/object:Gem::Dependency
@@ -193,10 +193,9 @@ files:
193
193
  - lib/sensu/client.rb
194
194
  - lib/sensu/constants.rb
195
195
  - lib/sensu/logger.rb
196
- - lib/sensu/patches/amqp.rb
197
- - lib/sensu/patches/redis.rb
198
196
  - lib/sensu/patches/ruby.rb
199
197
  - lib/sensu/process.rb
198
+ - lib/sensu/redis.rb
200
199
  - lib/sensu/server.rb
201
200
  - lib/sensu/settings.rb
202
201
  - lib/sensu/socket.rb
@@ -1,7 +0,0 @@
1
- module AMQP
2
- module Client
3
- def reconnecting?
4
- @reconnecting || false
5
- end
6
- end
7
- end
@@ -1,71 +0,0 @@
1
- module Redis
2
- class Client
3
- attr_accessor :redis_host, :redis_port, :redis_password
4
-
5
- def connection_completed
6
- @connected = true
7
- @reconnecting = false
8
- if @redis_password
9
- auth(@redis_password).callback do |reply|
10
- unless reply == 'OK'
11
- raise('could not authenticate')
12
- end
13
- end
14
- end
15
- info.callback do |reply|
16
- redis_version = reply.split(/\n/).first.split(/:/).last.chomp
17
- if redis_version < '1.3.14'
18
- raise('redis version must be >= 2.0 RC 1')
19
- end
20
- end
21
- end
22
-
23
- def close
24
- @closing_connection = true
25
- close_connection_after_writing
26
- end
27
-
28
- def unbind
29
- unless !@connected || @closing_connection
30
- EM::Timer.new(1) do
31
- @reconnecting = true
32
- reconnect(@redis_host, @redis_port)
33
- end
34
- else
35
- until @queue.empty?
36
- @queue.shift.fail RuntimeError.new('connection closed')
37
- end
38
- unless @connected
39
- raise('could not connect to redis')
40
- end
41
- end
42
- end
43
-
44
- def reconnecting?
45
- @reconnecting || false
46
- end
47
- end
48
-
49
- def self.connect(options)
50
- options ||= Hash.new
51
- if options.is_a?(String)
52
- begin
53
- uri = URI.parse(options)
54
- host = uri.host
55
- port = uri.port || 6379
56
- password = uri.password
57
- rescue
58
- raise('invalid redis url')
59
- end
60
- else
61
- host = options[:host] || 'localhost'
62
- port = options[:port] || 6379
63
- password = options[:password]
64
- end
65
- EM::connect(host, port, Redis::Client) do |client|
66
- client.redis_host = host
67
- client.redis_port = port
68
- client.redis_password = password
69
- end
70
- end
71
- end