sensu 0.9.9.beta.1 → 0.9.9.beta.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -11,6 +11,10 @@ Aggregate results available via the API when using a parameter
11
11
  Event filters; filtering events for handlers, using event attribute
12
12
  matching.
13
13
 
14
+ TCP handler socket timeout, which defaults to 10 seconds.
15
+
16
+ Check execution timeout.
17
+
14
18
  ### Other
15
19
 
16
20
  Server is now using basic AMQP QoS (prefetch), just enough back pressure.
data/lib/sensu/base.rb CHANGED
@@ -4,6 +4,7 @@ gem 'eventmachine', '1.0.0'
4
4
  gem 'amqp', '0.9.7'
5
5
 
6
6
  require 'json'
7
+ require 'timeout'
7
8
  require 'time'
8
9
  require 'uri'
9
10
  require 'amqp'
@@ -13,6 +14,7 @@ require File.join(File.dirname(__FILE__), 'cli')
13
14
  require File.join(File.dirname(__FILE__), 'logger')
14
15
  require File.join(File.dirname(__FILE__), 'settings')
15
16
  require File.join(File.dirname(__FILE__), 'process')
17
+ require File.join(File.dirname(__FILE__), 'io')
16
18
 
17
19
  module Sensu
18
20
  class Base
data/lib/sensu/client.rb CHANGED
@@ -102,10 +102,7 @@ module Sensu
102
102
  execute = Proc.new do
103
103
  started = Time.now.to_f
104
104
  begin
105
- IO.popen(command + ' 2>&1') do |io|
106
- check[:output] = io.read
107
- end
108
- check[:status] = $?.exitstatus
105
+ check[:output], check[:status] = Sensu::IO.popen(command, 'r', check[:timeout])
109
106
  rescue => error
110
107
  @logger.warn('unexpected error', {
111
108
  :error => error.to_s
@@ -117,9 +114,7 @@ module Sensu
117
114
  check
118
115
  end
119
116
  publish = Proc.new do |check|
120
- unless check[:status].nil?
121
- publish_result(check)
122
- end
117
+ publish_result(check)
123
118
  @checks_in_progress.delete(check[:name])
124
119
  end
125
120
  EM::defer(execute, publish)
@@ -1,6 +1,6 @@
1
1
  module Sensu
2
2
  unless defined?(Sensu::VERSION)
3
- VERSION = '0.9.9.beta.1'
3
+ VERSION = '0.9.9.beta.2'
4
4
  end
5
5
 
6
6
  unless defined?(Sensu::DEFAULT_OPTIONS)
data/lib/sensu/io.rb ADDED
@@ -0,0 +1,55 @@
1
+ module Sensu
2
+ class IO
3
+ class << self
4
+ def popen(command, mode='r', timeout=nil, &block)
5
+ block ||= Proc.new {}
6
+ begin
7
+ if RUBY_VERSION < '1.9.3'
8
+ child = ::IO.popen(command + ' 2>&1', mode)
9
+ block.call(child)
10
+ wait_on_process(child)
11
+ else
12
+ options = {
13
+ :err => [:child, :out]
14
+ }
15
+ case RUBY_PLATFORM
16
+ when /(ms|cyg|bcc)win|mingw|win32/
17
+ shell = ['cmd', '/c']
18
+ options[:new_pgroup] = true
19
+ else
20
+ shell = ['sh', '-c']
21
+ options[:pgroup] = true
22
+ end
23
+ child = ::IO.popen(shell + [command, options], mode)
24
+ if timeout
25
+ Timeout.timeout(timeout) do
26
+ block.call(child)
27
+ wait_on_process(child)
28
+ end
29
+ else
30
+ block.call(child)
31
+ wait_on_process(child)
32
+ end
33
+ end
34
+ rescue Timeout::Error
35
+ begin
36
+ ::Process.kill(9, -child.pid)
37
+ loop do
38
+ ::Process.wait2(-child.pid)
39
+ end
40
+ rescue Errno::ESRCH, Errno::ECHILD
41
+ ['Execution timed out', 2]
42
+ end
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def wait_on_process(process)
49
+ output = process.read
50
+ _, status = ::Process.wait2(process.pid)
51
+ [output, status.exitstatus]
52
+ end
53
+ end
54
+ end
55
+ end
data/lib/sensu/server.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require File.join(File.dirname(__FILE__), 'base')
2
2
  require File.join(File.dirname(__FILE__), 'redis')
3
+ require File.join(File.dirname(__FILE__), 'socket')
3
4
 
4
5
  module Sensu
5
6
  class Server
@@ -232,15 +233,12 @@ module Sensu
232
233
  end
233
234
  execute = Proc.new do
234
235
  begin
235
- output = ''
236
- IO.popen(command + ' 2>&1', 'r+') do |io|
236
+ output, status = Sensu::IO.popen(command, 'r+') do |child|
237
237
  unless data.nil?
238
- io.write(data.to_s)
238
+ child.write(data.to_s)
239
239
  end
240
- io.close_write
241
- output = io.read
240
+ child.close_write
242
241
  end
243
- status = $?.exitstatus
244
242
  [true, output, status]
245
243
  rescue => error
246
244
  on_error.call(error)
@@ -278,13 +276,11 @@ module Sensu
278
276
  })
279
277
  end
280
278
  execute_command(mutator[:command], event.to_json, on_error) do |output, status|
281
- if status != 0
282
- @logger.warn('mutator had a non-zero exit status', {
283
- :event => event,
284
- :mutator => mutator
285
- })
279
+ if status == 0
280
+ block.call(output)
281
+ else
282
+ on_error.call('non-zero exit status (' + status + '): ' + output)
286
283
  end
287
- block.call(output)
288
284
  end
289
285
  else
290
286
  @logger.error('unknown mutator', {
@@ -324,10 +320,16 @@ module Sensu
324
320
  end
325
321
  when 'tcp'
326
322
  begin
327
- EM::connect(handler[:socket][:host], handler[:socket][:port], nil) do |socket|
323
+ EM::connect(handler[:socket][:host], handler[:socket][:port], Sensu::SocketHandler) do |socket|
324
+ socket.on_success = Proc.new do
325
+ @handlers_in_progress_count -= 1
326
+ end
327
+ socket.on_error = on_error
328
+ timeout = handler[:socket][:timeout] || 10
329
+ socket.pending_connect_timeout = timeout
330
+ socket.comm_inactivity_timeout = timeout
328
331
  socket.send_data(event_data.to_s)
329
332
  socket.close_connection_after_writing
330
- @handlers_in_progress_count -= 1
331
333
  end
332
334
  rescue => error
333
335
  on_error.call(error)
@@ -204,6 +204,13 @@ module Sensu
204
204
  end
205
205
  end
206
206
  end
207
+ if check.has_key?(:timeout)
208
+ unless check[:timeout].is_a?(Numeric)
209
+ invalid('check timeout must be numeric', {
210
+ :check => check
211
+ })
212
+ end
213
+ end
207
214
  if check.has_key?(:handler)
208
215
  unless check[:handler].is_a?(String)
209
216
  invalid('check handler must be a string', {
@@ -398,6 +405,13 @@ module Sensu
398
405
  :handler => handler
399
406
  })
400
407
  end
408
+ if handler[:socket].has_key?(:timeout)
409
+ unless handler[:socket][:timeout].is_a?(Integer)
410
+ invalid('handler socket timeout must be an integer', {
411
+ :handler => handler
412
+ })
413
+ end
414
+ end
401
415
  when 'amqp'
402
416
  unless handler[:exchange].is_a?(Hash)
403
417
  invalid('handler is missing exchange hash', {
data/lib/sensu/socket.rb CHANGED
@@ -49,4 +49,26 @@ module Sensu
49
49
  end
50
50
  end
51
51
  end
52
+
53
+ class SocketHandler < EM::Connection
54
+ attr_accessor :on_success, :on_error
55
+
56
+ def connection_completed
57
+ @connected_at = Time.now.to_f
58
+ @inactivity_timeout = comm_inactivity_timeout
59
+ end
60
+
61
+ def unbind
62
+ if @connected_at
63
+ elapsed_time = Time.now.to_f - @connected_at
64
+ if elapsed_time >= @inactivity_timeout
65
+ @on_error.call('socket inactivity timeout')
66
+ else
67
+ @on_success.call('wrote to socket')
68
+ end
69
+ else
70
+ @on_error.call('failed to connect to socket')
71
+ end
72
+ end
73
+ end
52
74
  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: 1653984923
4
+ hash: -1743839652
5
5
  prerelease: true
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
9
  - 9
10
10
  - beta
11
- - 1
12
- version: 0.9.9.beta.1
11
+ - 2
12
+ version: 0.9.9.beta.2
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-12-06 00:00:00 -08:00
21
+ date: 2013-01-02 00:00:00 -08:00
22
22
  default_executable:
23
23
  dependencies:
24
24
  - !ruby/object:Gem::Dependency
@@ -198,6 +198,7 @@ files:
198
198
  - lib/sensu/client.rb
199
199
  - lib/sensu/process.rb
200
200
  - lib/sensu/cli.rb
201
+ - lib/sensu/io.rb
201
202
  - lib/sensu/base.rb
202
203
  - lib/sensu/logger.rb
203
204
  - lib/sensu.rb