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 +1 -1
- data/Gemfile.lock +2 -2
- data/README.org +3 -1
- data/lib/sensu/api.rb +13 -8
- data/lib/sensu/client.rb +8 -4
- data/lib/sensu/config.rb +20 -4
- data/lib/sensu/helpers/redis.rb +25 -0
- data/lib/sensu/helpers/ruby.rb +46 -0
- data/lib/sensu/server.rb +11 -5
- data/lib/sensu.rb +1 -1
- data/sensu.gemspec +1 -1
- metadata +7 -6
- data/lib/sensu/helpers.rb +0 -26
data/Gemfile
CHANGED
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
|
|
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
|
|
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-
|
|
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 =>
|
|
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
|
-
|
|
27
|
+
$settings = config.settings
|
|
26
28
|
$logger = config.logger
|
|
27
29
|
$logger.debug('[setup] -- connecting to redis')
|
|
28
|
-
$redis = EM.connect(
|
|
30
|
+
$redis = EM.connect($settings.redis.host, $settings.redis.port, Redis::Reconnect)
|
|
29
31
|
$logger.debug('[setup] -- connecting to rabbitmq')
|
|
30
|
-
connection = AMQP.connect(
|
|
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:' +
|
|
233
|
-
$redis.sadd('clients',
|
|
234
|
-
$redis.hset('events:' +
|
|
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 =>
|
|
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
|
|
88
|
-
|
|
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] --
|
|
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 =>
|
|
38
|
-
invalid_config('configuration file must be valid JSON: ' +
|
|
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::
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
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
|
|
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:
|
|
4
|
+
hash: 27
|
|
5
5
|
prerelease: false
|
|
6
6
|
segments:
|
|
7
7
|
- 0
|
|
8
8
|
- 8
|
|
9
|
-
-
|
|
10
|
-
version: 0.8.
|
|
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-
|
|
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
|
|
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
|