sensu 0.8.16 → 0.8.18

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/Gemfile CHANGED
@@ -6,7 +6,7 @@ gem("amqp", "0.7.4")
6
6
  gem("json")
7
7
  gem("hashie")
8
8
  gem("cabin", "0.1.7")
9
- gem("ruby-redis-portertech")
9
+ gem("ruby-redis")
10
10
  gem("rack", "~> 1.3.4")
11
11
  gem("async_sinatra")
12
12
  gem("thin")
data/Gemfile.lock CHANGED
@@ -40,7 +40,7 @@ GEM
40
40
  rspec-expectations (2.6.0)
41
41
  diff-lcs (~> 1.1.2)
42
42
  rspec-mocks (2.6.0)
43
- ruby-redis-portertech (0.0.3)
43
+ ruby-redis (0.0.2)
44
44
  eventmachine
45
45
  sinatra (1.3.1)
46
46
  rack (~> 1.3, >= 1.3.4)
@@ -68,5 +68,5 @@ DEPENDENCIES
68
68
  json
69
69
  rack (~> 1.3.4)
70
70
  rake
71
- ruby-redis-portertech
71
+ ruby-redis
72
72
  thin
data/README.org CHANGED
@@ -9,7 +9,7 @@
9
9
  * Documentation
10
10
  Find it [[https://github.com/sonian/sensu/wiki][HERE]].
11
11
  * Other Projects
12
- - [[https://github.com/sonian/sensu-plugins][Sensu Community Plugins]]
12
+ - [[https://github.com/sonian/sensu-plugin][Sensu Community Plugins]]
13
13
  - [[https://github.com/sonian/sensu-dashboard][Sensu Dashboard]]
14
14
  * License
15
15
  Sensu is released under the [[https://github.com/sonian/sensu/blob/master/MIT-LICENSE.txt][MIT license]].
@@ -34,3 +34,5 @@
34
34
  - [[http://twitter.com/amdprophet][Justin Kolberg]]
35
35
  - [[http://twitter.com/kartar][James Turnbull]]
36
36
  - [[http://twitter.com/joshpasqualetto][Josh Pasqualetto]]
37
+ - Steve Lum
38
+ - [[http://twitter.com/miller_joe][Joe Miller]]
data/lib/sensu/api.rb CHANGED
@@ -3,6 +3,8 @@ require File.join(File.dirname(__FILE__), 'config')
3
3
  require 'sinatra/async'
4
4
  require 'redis'
5
5
 
6
+ require File.join(File.dirname(__FILE__), 'helpers', 'redis')
7
+
6
8
  module Sensu
7
9
  class API < Sinatra::Base
8
10
  register Sinatra::Async
@@ -10,7 +12,7 @@ module Sensu
10
12
  def self.run(options={})
11
13
  EM.run do
12
14
  self.setup(options)
13
- self.run!(:port => @settings.api.port)
15
+ self.run!(:port => $settings.api.port)
14
16
 
15
17
  %w[INT TERM].each do |signal|
16
18
  Signal.trap(signal) do
@@ -22,12 +24,12 @@ module Sensu
22
24
 
23
25
  def self.setup(options={})
24
26
  config = Sensu::Config.new(options)
25
- @settings = config.settings
27
+ $settings = config.settings
26
28
  $logger = config.logger
27
29
  $logger.debug('[setup] -- connecting to redis')
28
- $redis = EM.connect(@settings.redis.host, @settings.redis.port, Redis::Client)
30
+ $redis = EM.connect($settings.redis.host, $settings.redis.port, Redis::Reconnect)
29
31
  $logger.debug('[setup] -- connecting to rabbitmq')
30
- connection = AMQP.connect(@settings.rabbitmq.to_hash.symbolize_keys)
32
+ connection = AMQP.connect($settings.rabbitmq.to_hash.symbolize_keys)
31
33
  $amq = MQ.new(connection)
32
34
  end
33
35
 
@@ -86,6 +88,9 @@ module Sensu
86
88
  $redis.srem('clients', client)
87
89
  $redis.del('events:' + client)
88
90
  $redis.del('client:' + client)
91
+ $settings.checks.each_key do |check_name|
92
+ $redis.del('history:' + client + ':' + check_name)
93
+ end
89
94
  end
90
95
  status 204
91
96
  body nil
@@ -229,16 +234,16 @@ module Sensu
229
234
 
230
235
  def self.test(options={})
231
236
  self.setup(options)
232
- $redis.set('client:' + @settings.client.name, @settings.client.to_json).callback do
233
- $redis.sadd('clients', @settings.client.name).callback do
234
- $redis.hset('events:' + @settings.client.name, 'test', {
237
+ $redis.set('client:' + $settings.client.name, $settings.client.to_json).callback do
238
+ $redis.sadd('clients', $settings.client.name).callback do
239
+ $redis.hset('events:' + $settings.client.name, 'test', {
235
240
  :status => 2,
236
241
  :output => 'CRITICAL',
237
242
  :flapping => false,
238
243
  :occurrences => 1
239
244
  }.to_json).callback do
240
245
  $redis.set('stash:test/test', '{"key": "value"}').callback do
241
- self.run!(:port => @settings.api.port)
246
+ self.run!(:port => $settings.api.port)
242
247
  end
243
248
  end
244
249
  end
data/lib/sensu/client.rb CHANGED
@@ -84,8 +84,12 @@ module Sensu
84
84
  end
85
85
  check.status = $?.exitstatus
86
86
  end
87
- publish = proc do |result|
88
- publish_result(check)
87
+ publish = proc do
88
+ unless check.status.nil?
89
+ publish_result(check)
90
+ else
91
+ @logger.warn('[execute] -- nil exit status code -- ' + check.name)
92
+ end
89
93
  @checks_in_progress.delete(check.name)
90
94
  end
91
95
  EM.defer(execute, publish)
@@ -182,8 +186,8 @@ module Sensu
182
186
  else
183
187
  @logger.warn('[socket] -- a check name, exit status, and output are required -- e.g. {name: x, status: 0, output: "y"}')
184
188
  end
185
- rescue JSON::ParserError
186
- @logger.warn('[socket] -- could not parse check result -- expecting JSON')
189
+ rescue JSON::ParserError => error
190
+ @logger.warn('[socket] -- check result must be valid JSON: ' + error)
187
191
  end
188
192
  close_connection
189
193
  end
data/lib/sensu/config.rb CHANGED
@@ -1,9 +1,9 @@
1
+ require File.join(File.dirname(__FILE__), 'helpers', 'ruby')
2
+
1
3
  require 'rubygems' if RUBY_VERSION < '1.9.0'
2
4
  require 'bundler'
3
5
  require 'bundler/setup'
4
6
 
5
- require File.join(File.dirname(__FILE__), 'helpers')
6
-
7
7
  gem 'eventmachine', '~> 1.0.0.beta.4'
8
8
 
9
9
  require 'optparse'
@@ -34,12 +34,25 @@ module Sensu
34
34
  if File.readable?(config_file)
35
35
  begin
36
36
  @settings = Hashie::Mash.new(JSON.parse(File.open(config_file, 'r').read))
37
- rescue JSON::ParserError => e
38
- invalid_config('configuration file must be valid JSON: ' + e)
37
+ rescue JSON::ParserError => error
38
+ invalid_config('configuration file (' + config_file + ') must be valid JSON: ' + error)
39
39
  end
40
40
  else
41
41
  invalid_config('configuration file does not exist or is not readable: ' + config_file)
42
42
  end
43
+ config_dir = options[:config_dir] || '/etc/sensu/conf.d'
44
+ if File.exists?(config_dir)
45
+ Dir[config_dir + '/**/*.json'].each do |snippet_file|
46
+ begin
47
+ snippet_hash = JSON.parse(File.open(snippet_file, 'r').read)
48
+ rescue JSON::ParserError => error
49
+ invalid_config('configuration snippet file (' + snippet_file + ') must be valid JSON: ' + error)
50
+ end
51
+ merged_settings = @settings.to_hash.deep_merge(snippet_hash)
52
+ @logger.warn('[settings] configuration snippet (' + snippet_file + ') applied changes: ' + @settings.deep_diff(merged_settings).to_json)
53
+ @settings = Hashie::Mash.new(merged_settings)
54
+ end
55
+ end
43
56
  validate_config(options['type'])
44
57
  end
45
58
 
@@ -122,6 +135,9 @@ module Sensu
122
135
  opts.on('-c', '--config FILE', 'Sensu JSON config FILE (default: /etc/sensu/config.json)') do |file|
123
136
  options[:config_file] = file
124
137
  end
138
+ opts.on('-d', '--config_dir DIR', 'Directory for supplemental Sensu JSON config files (default: /etc/sensu/conf.d/)') do |dir|
139
+ options[:config_dir] = dir
140
+ end
125
141
  opts.on('-l', '--log FILE', 'Sensu log FILE (default: /tmp/sensu.log)') do |file|
126
142
  options[:log_file] = file
127
143
  end
@@ -0,0 +1,25 @@
1
+ module Redis
2
+ class Reconnect < Redis::Client
3
+ def connection_completed
4
+ @connected = true
5
+ @port, @host = Socket.unpack_sockaddr_in(get_peername)
6
+ end
7
+
8
+ def close
9
+ @closing_connection = true
10
+ close_connection_after_writing
11
+ end
12
+
13
+ def unbind
14
+ unless !@connected || @closing_connection
15
+ EM.add_timer(1) do
16
+ reconnect(@host, @port)
17
+ end
18
+ else
19
+ until @queue.empty?
20
+ @queue.shift.fail RuntimeError.new 'connection closed'
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,46 @@
1
+ class Hash
2
+ def symbolize_keys(item=self)
3
+ case item
4
+ when Array
5
+ item.map do |i|
6
+ symbolize_keys(i)
7
+ end
8
+ when Hash
9
+ Hash[
10
+ item.map do |key, value|
11
+ new_key = key.is_a?(String) ? key.to_sym : key
12
+ new_value = symbolize_keys(value)
13
+ [new_key, new_value]
14
+ end
15
+ ]
16
+ else
17
+ item
18
+ end
19
+ end
20
+
21
+ def deep_diff(hash)
22
+ (self.keys | hash.keys).inject(Hash.new) do |diff, key|
23
+ unless self[key] == hash[key]
24
+ if self[key].is_a?(Hash) && hash[key].is_a?(Hash)
25
+ diff[key] = self[key].deep_diff(hash[key])
26
+ else
27
+ diff[key] = [self[key], hash[key]]
28
+ end
29
+ end
30
+ diff
31
+ end
32
+ end
33
+
34
+ def deep_merge(hash)
35
+ merger = proc do |key, value1, value2|
36
+ value1.is_a?(Hash) && value2.is_a?(Hash) ? value1.merge(value2, &merger) : value2
37
+ end
38
+ self.merge(hash, &merger)
39
+ end
40
+ end
41
+
42
+ class String
43
+ def self.unique(chars=32)
44
+ rand(36**chars).to_s(36)
45
+ end
46
+ end
data/lib/sensu/server.rb CHANGED
@@ -2,6 +2,8 @@ require File.join(File.dirname(__FILE__), 'config')
2
2
 
3
3
  require 'redis'
4
4
 
5
+ require File.join(File.dirname(__FILE__), 'helpers', 'redis')
6
+
5
7
  module Sensu
6
8
  class Server
7
9
  attr_accessor :redis, :is_worker
@@ -44,7 +46,7 @@ module Sensu
44
46
 
45
47
  def setup_redis
46
48
  @logger.debug('[redis] -- connecting to redis')
47
- @redis = EM.connect(@settings.redis.host, @settings.redis.port, Redis::Client)
49
+ @redis = EM.connect(@settings.redis.host, @settings.redis.port, Redis::Reconnect)
48
50
  end
49
51
 
50
52
  def setup_amqp
@@ -85,10 +87,14 @@ module Sensu
85
87
  handle = proc do
86
88
  output = ''
87
89
  Bundler.with_clean_env do
88
- IO.popen(@settings.handlers[handler] + ' 2>&1', 'r+') do |io|
89
- io.write(event.to_json)
90
- io.close_write
91
- output = io.read
90
+ begin
91
+ IO.popen(@settings.handlers[handler] + ' 2>&1', 'r+') do |io|
92
+ io.write(event.to_json)
93
+ io.close_write
94
+ output = io.read
95
+ end
96
+ rescue Errno::EPIPE => error
97
+ output = handler + ' -- broken pipe: ' + error
92
98
  end
93
99
  end
94
100
  output
data/lib/sensu.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Sensu
2
- VERSION = "0.8.16"
2
+ VERSION = "0.8.18"
3
3
  end
data/sensu.gemspec CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
18
18
  s.add_dependency("json")
19
19
  s.add_dependency("hashie")
20
20
  s.add_dependency("cabin", "0.1.7")
21
- s.add_dependency("ruby-redis-portertech")
21
+ s.add_dependency("ruby-redis")
22
22
  s.add_dependency("rack", "~> 1.3.4")
23
23
  s.add_dependency("async_sinatra")
24
24
  s.add_dependency("thin")
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sensu
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 8
9
- - 16
10
- version: 0.8.16
9
+ - 18
10
+ version: 0.8.18
11
11
  platform: ruby
12
12
  authors:
13
13
  - Sean Porter
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-12-02 00:00:00 -08:00
19
+ date: 2011-12-13 00:00:00 -08:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -112,7 +112,7 @@ dependencies:
112
112
  type: :runtime
113
113
  version_requirements: *id006
114
114
  - !ruby/object:Gem::Dependency
115
- name: ruby-redis-portertech
115
+ name: ruby-redis
116
116
  prerelease: false
117
117
  requirement: &id007 !ruby/object:Gem::Requirement
118
118
  none: false
@@ -238,7 +238,8 @@ files:
238
238
  - lib/sensu/api.rb
239
239
  - lib/sensu/client.rb
240
240
  - lib/sensu/config.rb
241
- - lib/sensu/helpers.rb
241
+ - lib/sensu/helpers/redis.rb
242
+ - lib/sensu/helpers/ruby.rb
242
243
  - lib/sensu/server.rb
243
244
  - sensu.gemspec
244
245
  has_rdoc: true
data/lib/sensu/helpers.rb DELETED
@@ -1,26 +0,0 @@
1
- class Hash
2
- def symbolize_keys(item=self)
3
- case item
4
- when Array
5
- item.map do |i|
6
- symbolize_keys(i)
7
- end
8
- when Hash
9
- Hash[
10
- item.map do |key, value|
11
- new_key = key.is_a?(String) ? key.to_sym : key
12
- new_value = symbolize_keys(value)
13
- [new_key, new_value]
14
- end
15
- ]
16
- else
17
- item
18
- end
19
- end
20
- end
21
-
22
- class String
23
- def self.unique(chars=32)
24
- rand(36**chars).to_s(36)
25
- end
26
- end