sensu 0.9.4 → 0.9.5.beta
Sign up to get free protection for your applications and to get access to all the features.
- data/README.org +0 -2
- data/lib/sensu.rb +1 -1
- data/lib/sensu/api.rb +23 -13
- data/lib/sensu/client.rb +19 -9
- data/lib/sensu/config.rb +3 -2
- data/lib/sensu/patches/redis.rb +8 -1
- data/lib/sensu/server.rb +6 -6
- metadata +12 -9
data/README.org
CHANGED
@@ -6,13 +6,11 @@
|
|
6
6
|
[[http://portertech.ca/2011/11/01/sensu-a-monitoring-framework][Blog post]]
|
7
7
|
|
8
8
|
[[http://www.sonian.com/cloud-tools/cloud-monitoring-sensu/][Homepage]]
|
9
|
-
|
10
9
|
* Documentation
|
11
10
|
- [[https://github.com/sonian/sensu/wiki][Sensu Wiki]].
|
12
11
|
- [[http://joemiller.me/2012/01/19/getting-started-with-the-sensu-monitoring-framework/][Getting Started]]
|
13
12
|
- [[http://joemiller.me/2012/01/24/re-use-nagios-plugins-in-sensu-for-quick-profit/][How to reuse your existing Nagios plugins]]
|
14
13
|
- [[http://joemiller.me/2012/02/02/sensu-and-graphite/][Sensu and Graphite]]
|
15
|
-
|
16
14
|
* Other Projects
|
17
15
|
- [[https://github.com/sonian/sensu-community-plugins][Sensu Community Plugins]]
|
18
16
|
- [[https://github.com/sonian/sensu-dashboard][Sensu Dashboard]]
|
data/lib/sensu.rb
CHANGED
data/lib/sensu/api.rb
CHANGED
@@ -46,6 +46,16 @@ module Sensu
|
|
46
46
|
content_type 'application/json'
|
47
47
|
end
|
48
48
|
|
49
|
+
aget '/info' do
|
50
|
+
$logger.debug('[info] -- ' + request.ip + ' -- GET -- request for sensu info')
|
51
|
+
response = {
|
52
|
+
:sensu => {
|
53
|
+
:version => Sensu::VERSION
|
54
|
+
}
|
55
|
+
}
|
56
|
+
body response.to_json
|
57
|
+
end
|
58
|
+
|
49
59
|
aget '/clients' do
|
50
60
|
$logger.debug('[clients] -- ' + request.ip + ' -- GET -- request for client list')
|
51
61
|
response = Array.new
|
@@ -86,9 +96,9 @@ module Sensu
|
|
86
96
|
$logger.info('[client] -- publishing check result to resolve event -- ' + client + ' -- ' + check_name)
|
87
97
|
check = {
|
88
98
|
:name => check_name,
|
89
|
-
:issued => Time.now.to_i,
|
90
|
-
:status => 0,
|
91
99
|
:output => 'Client is being removed on request of the API',
|
100
|
+
:status => 0,
|
101
|
+
:issued => Time.now.to_i,
|
92
102
|
:force_resolve => true
|
93
103
|
}
|
94
104
|
$amq.queue('results').publish({:client => client, :check => check}.to_json)
|
@@ -150,16 +160,13 @@ module Sensu
|
|
150
160
|
|
151
161
|
aget '/events' do
|
152
162
|
$logger.debug('[events] -- ' + request.ip + ' -- GET -- request for event list')
|
153
|
-
response =
|
163
|
+
response = Array.new
|
154
164
|
$redis.smembers('clients').callback do |clients|
|
155
165
|
unless clients.empty?
|
156
166
|
clients.each_with_index do |client, index|
|
157
167
|
$redis.hgetall('events:' + client).callback do |events|
|
158
|
-
events.each do |
|
159
|
-
|
160
|
-
end
|
161
|
-
unless events.empty?
|
162
|
-
response[client] = events
|
168
|
+
events.each do |check, details|
|
169
|
+
response.push(JSON.parse(details).merge(:client => client, :check => check))
|
163
170
|
end
|
164
171
|
if index == clients.size - 1
|
165
172
|
body response.to_json
|
@@ -176,10 +183,13 @@ module Sensu
|
|
176
183
|
$logger.debug('[event] -- ' + request.ip + ' -- GET -- request for event -- ' + client + ' -- ' + check)
|
177
184
|
$redis.hgetall('events:' + client).callback do |events|
|
178
185
|
event_json = events[check]
|
179
|
-
|
186
|
+
unless event_json.nil?
|
187
|
+
response = JSON.parse(event_json).merge(:client => client, :check => check)
|
188
|
+
body response.to_json
|
189
|
+
else
|
180
190
|
status 404
|
191
|
+
body ''
|
181
192
|
end
|
182
|
-
body event_json
|
183
193
|
end
|
184
194
|
end
|
185
195
|
|
@@ -197,9 +207,9 @@ module Sensu
|
|
197
207
|
$logger.info('[event] -- publishing check result to resolve event -- ' + post_body.client + ' -- ' + post_body.check)
|
198
208
|
check = {
|
199
209
|
:name => post_body.check,
|
200
|
-
:issued => Time.now.to_i,
|
201
|
-
:status => 0,
|
202
210
|
:output => 'Resolving on request of the API',
|
211
|
+
:status => 0,
|
212
|
+
:issued => Time.now.to_i,
|
203
213
|
:force_resolve => true
|
204
214
|
}
|
205
215
|
$amq.queue('results').publish({:client => post_body.client, :check => check}.to_json)
|
@@ -297,8 +307,8 @@ module Sensu
|
|
297
307
|
$redis.set('client:' + $settings.client.name, $settings.client.to_json).callback do
|
298
308
|
$redis.sadd('clients', $settings.client.name).callback do
|
299
309
|
$redis.hset('events:' + $settings.client.name, 'test', {
|
300
|
-
:status => 2,
|
301
310
|
:output => "CRITICAL\n",
|
311
|
+
:status => 2,
|
302
312
|
:issued => Time.now.utc.iso8601,
|
303
313
|
:flapping => false,
|
304
314
|
:occurrences => 1
|
data/lib/sensu/client.rb
CHANGED
@@ -56,7 +56,7 @@ module Sensu
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def publish_result(check)
|
59
|
-
@logger.info('[result] -- publishing check result -- ' + [check.name, check.status, check.output].join(' -- '))
|
59
|
+
@logger.info('[result] -- publishing check result -- ' + [check.name, check.status, check.output.gsub(/\n/, '\n')].join(' -- '))
|
60
60
|
@amq.queue('results').publish({
|
61
61
|
:client => @settings.client.name,
|
62
62
|
:check => check.to_hash
|
@@ -91,12 +91,14 @@ module Sensu
|
|
91
91
|
IO.popen(command + ' 2>&1') do |io|
|
92
92
|
check.output = io.read
|
93
93
|
end
|
94
|
+
check.status = $?.exitstatus
|
94
95
|
rescue => error
|
95
|
-
|
96
|
+
@logger.warn('[execute] -- unexpected error: ' + error.to_s)
|
97
|
+
check.output = 'Unexpected error: ' + error.to_s
|
98
|
+
check.status = 2
|
96
99
|
end
|
97
100
|
check.duration = ('%.3f' % (Time.now.to_f - started)).to_f
|
98
101
|
end
|
99
|
-
check.status = $?.exitstatus
|
100
102
|
end
|
101
103
|
publish = proc do
|
102
104
|
unless check.status.nil?
|
@@ -109,8 +111,8 @@ module Sensu
|
|
109
111
|
EM::defer(execute, publish)
|
110
112
|
else
|
111
113
|
@logger.warn('[execute] -- missing client attributes -- ' + unmatched_tokens.join(', ') + ' -- ' + check.name)
|
112
|
-
check.status = 3
|
113
114
|
check.output = 'Missing client attributes: ' + unmatched_tokens.join(', ')
|
115
|
+
check.status = 3
|
114
116
|
check.handle = false
|
115
117
|
publish_result(check)
|
116
118
|
@checks_in_progress.delete(check.name)
|
@@ -120,8 +122,8 @@ module Sensu
|
|
120
122
|
end
|
121
123
|
else
|
122
124
|
@logger.warn('[execute] -- unkown check -- ' + check.name)
|
123
|
-
check.status = 3
|
124
125
|
check.output = 'Unknown check'
|
126
|
+
check.status = 3
|
125
127
|
check.handle = false
|
126
128
|
publish_result(check)
|
127
129
|
@checks_in_progress.delete(check.name)
|
@@ -137,9 +139,17 @@ module Sensu
|
|
137
139
|
@check_request_queue.bind(@amq.fanout(exchange))
|
138
140
|
end
|
139
141
|
@check_request_queue.subscribe do |check_request_json|
|
140
|
-
|
141
|
-
|
142
|
-
|
142
|
+
begin
|
143
|
+
check = Hashie::Mash.new(JSON.parse(check_request_json))
|
144
|
+
if check.name.is_a?(String) && check.issued.is_a?(Integer)
|
145
|
+
@logger.info('[subscribe] -- received check request -- ' + check.name)
|
146
|
+
execute_check(check)
|
147
|
+
else
|
148
|
+
@logger.warn('[subscribe] -- invalid check request: ' + check_request_json)
|
149
|
+
end
|
150
|
+
rescue JSON::ParserError => error
|
151
|
+
@logger.warn('[subscribe] -- check request must be valid JSON: ' + error.to_s)
|
152
|
+
end
|
143
153
|
end
|
144
154
|
end
|
145
155
|
|
@@ -229,7 +239,7 @@ module Sensu
|
|
229
239
|
check.issued = Time.now.to_i
|
230
240
|
check.status ||= 0
|
231
241
|
if validates && check.status.is_a?(Integer)
|
232
|
-
@logger.info('[socket] -- publishing check result -- ' + [check.name, check.status, check.output].join(' -- '))
|
242
|
+
@logger.info('[socket] -- publishing check result -- ' + [check.name, check.status, check.output.gsub(/\n/, '\n')].join(' -- '))
|
233
243
|
@amq.queue('results').publish({
|
234
244
|
:client => @settings.client.name,
|
235
245
|
:check => check.to_hash
|
data/lib/sensu/config.rb
CHANGED
@@ -12,6 +12,7 @@ require 'amqp'
|
|
12
12
|
require 'cabin'
|
13
13
|
require 'cabin/outputs/em/stdlib-logger'
|
14
14
|
|
15
|
+
require File.join(File.dirname(__FILE__), '..', 'sensu')
|
15
16
|
require File.join(File.dirname(__FILE__), 'patches', 'ruby')
|
16
17
|
require File.join(File.dirname(__FILE__), 'patches', 'amqp')
|
17
18
|
|
@@ -49,7 +50,7 @@ module Sensu
|
|
49
50
|
end
|
50
51
|
end
|
51
52
|
@logger = Cabin::Channel.new
|
52
|
-
log_output = File.basename($0) == 'rake' ? '/tmp/
|
53
|
+
log_output = File.basename($0) == 'rake' ? '/tmp/sensu-test.log' : STDOUT
|
53
54
|
@logger.subscribe(Cabin::Outputs::EM::StdlibLogger.new(Logger.new(log_output)))
|
54
55
|
@logger.level = @options[:verbose] ? :debug : :info
|
55
56
|
if Signal.list.include?('USR1')
|
@@ -62,7 +63,7 @@ module Sensu
|
|
62
63
|
def validate_common_settings
|
63
64
|
@settings.checks.each do |name, details|
|
64
65
|
if details.key?('status') || details.key?('output')
|
65
|
-
invalid_config('reserved key (
|
66
|
+
invalid_config('reserved key (output or status) defined in check ' + name)
|
66
67
|
end
|
67
68
|
unless details.interval.is_a?(Integer) && details.interval > 0
|
68
69
|
invalid_config('missing interval for check ' + name)
|
data/lib/sensu/patches/redis.rb
CHANGED
@@ -29,6 +29,13 @@ module Redis
|
|
29
29
|
def self.connect(options={})
|
30
30
|
host = options[:host] || 'localhost'
|
31
31
|
port = options[:port] || 6379
|
32
|
-
EM::connect(host, port, Redis::Client)
|
32
|
+
redis = EM::connect(host, port, Redis::Client)
|
33
|
+
redis.info do |info|
|
34
|
+
redis_version = info.split(/\n/).first.split(/:/).last
|
35
|
+
unless redis_version.to_i >= 2
|
36
|
+
raise "redis version must be >= 2.0"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
redis
|
33
40
|
end
|
34
41
|
end
|
data/lib/sensu/server.rb
CHANGED
@@ -178,8 +178,8 @@ module Sensu
|
|
178
178
|
event.occurrences = previous_occurrence.occurrences += 1
|
179
179
|
end
|
180
180
|
@redis.hset('events:' + client.name, check.name, {
|
181
|
-
:status => check.status,
|
182
181
|
:output => check.output,
|
182
|
+
:status => check.status,
|
183
183
|
:issued => Time.at(check.issued).utc.iso8601,
|
184
184
|
:flapping => is_flapping,
|
185
185
|
:occurrences => event.occurrences
|
@@ -228,7 +228,7 @@ module Sensu
|
|
228
228
|
@result_queue = @amq.queue('results')
|
229
229
|
@result_queue.subscribe do |result_json|
|
230
230
|
result = Hashie::Mash.new(JSON.parse(result_json))
|
231
|
-
@logger.info('[result] -- received result -- ' + [result.client, result.check.name, result.check.status, result.check.output].join(' -- '))
|
231
|
+
@logger.info('[result] -- received result -- ' + [result.client, result.check.name, result.check.status, result.check.output.gsub(/\n/, '\n')].join(' -- '))
|
232
232
|
process_result(result)
|
233
233
|
end
|
234
234
|
end
|
@@ -239,7 +239,7 @@ module Sensu
|
|
239
239
|
@settings.checks.each_with_index do |(name, details), index|
|
240
240
|
check_request = Hashie::Mash.new(:name => name)
|
241
241
|
unless details.publish == false || details.standalone
|
242
|
-
@timers << EM::Timer.new(stagger*index) do
|
242
|
+
@timers << EM::Timer.new(stagger * index) do
|
243
243
|
details.subscribers.each do |exchange|
|
244
244
|
interval = options[:test] ? 0.5 : details.interval
|
245
245
|
@timers << EM::PeriodicTimer.new(interval) do
|
@@ -271,18 +271,18 @@ module Sensu
|
|
271
271
|
)
|
272
272
|
case
|
273
273
|
when time_since_last_keepalive >= 180
|
274
|
-
result.check.status = 2
|
275
274
|
result.check.output = 'No keep-alive sent from host in over 180 seconds'
|
275
|
+
result.check.status = 2
|
276
276
|
@amq.queue('results').publish(result.to_json)
|
277
277
|
when time_since_last_keepalive >= 120
|
278
|
-
result.check.status = 1
|
279
278
|
result.check.output = 'No keep-alive sent from host in over 120 seconds'
|
279
|
+
result.check.status = 1
|
280
280
|
@amq.queue('results').publish(result.to_json)
|
281
281
|
else
|
282
282
|
@redis.hexists('events:' + client_id, 'keepalive').callback do |exists|
|
283
283
|
if exists
|
284
|
-
result.check.status = 0
|
285
284
|
result.check.output = 'Keep-alive sent from host'
|
285
|
+
result.check.status = 0
|
286
286
|
@amq.queue('results').publish(result.to_json)
|
287
287
|
end
|
288
288
|
end
|
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:
|
5
|
-
prerelease:
|
4
|
+
hash: 31098141
|
5
|
+
prerelease: true
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 9
|
9
|
-
-
|
10
|
-
|
9
|
+
- 5
|
10
|
+
- beta
|
11
|
+
version: 0.9.5.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: 2012-
|
20
|
+
date: 2012-03-05 00:00:00 -08:00
|
20
21
|
default_executable:
|
21
22
|
dependencies:
|
22
23
|
- !ruby/object:Gem::Dependency
|
@@ -245,12 +246,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
245
246
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
246
247
|
none: false
|
247
248
|
requirements:
|
248
|
-
- - "
|
249
|
+
- - ">"
|
249
250
|
- !ruby/object:Gem::Version
|
250
|
-
hash:
|
251
|
+
hash: 25
|
251
252
|
segments:
|
252
|
-
-
|
253
|
-
|
253
|
+
- 1
|
254
|
+
- 3
|
255
|
+
- 1
|
256
|
+
version: 1.3.1
|
254
257
|
requirements: []
|
255
258
|
|
256
259
|
rubyforge_project:
|