sensu 0.9.7.beta.1 → 0.9.7.beta.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +6 -0
- data/lib/sensu/api.rb +104 -79
- data/lib/sensu/client.rb +1 -1
- data/lib/sensu/constants.rb +1 -1
- data/lib/sensu/redis.rb +9 -0
- data/lib/sensu/server.rb +1 -1
- metadata +4 -4
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,10 @@
|
|
5
5
|
Event data mutators, manipulate event data and its format prior to
|
6
6
|
sending to a handler.
|
7
7
|
|
8
|
+
TCP and UDP handler types, for writing event data to sockets.
|
9
|
+
|
10
|
+
API resources now support singular & plural, Rails friendly.
|
11
|
+
|
8
12
|
### Non-backwards compatible changes
|
9
13
|
|
10
14
|
AMQP handlers can no longer use `"send_only_check_output": true`, but
|
@@ -13,6 +17,8 @@ instead have access to the built-in mutators `"mutator": "only_check_output"` an
|
|
13
17
|
|
14
18
|
### Other
|
15
19
|
|
20
|
+
Redis client connection heartbeat.
|
21
|
+
|
16
22
|
Improved graceful process termination.
|
17
23
|
|
18
24
|
Improved client socket ping/pong.
|
data/lib/sensu/api.rb
CHANGED
@@ -63,25 +63,6 @@ module Sensu
|
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
|
-
def healthy?
|
67
|
-
unless $redis.connected?
|
68
|
-
unless env['REQUEST_PATH'] == '/info'
|
69
|
-
halt 500
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def request_log
|
75
|
-
$logger.info([env['REQUEST_METHOD'], env['REQUEST_PATH']].join(' '), {
|
76
|
-
:remote_address => env['REMOTE_ADDR'],
|
77
|
-
:user_agent => env['HTTP_USER_AGENT'],
|
78
|
-
:request_method => env['REQUEST_METHOD'],
|
79
|
-
:request_uri => env['REQUEST_URI'],
|
80
|
-
:request_body => env['rack.input'].read
|
81
|
-
})
|
82
|
-
env['rack.input'].rewind
|
83
|
-
end
|
84
|
-
|
85
66
|
configure do
|
86
67
|
disable :protection
|
87
68
|
disable :show_exceptions
|
@@ -95,10 +76,55 @@ module Sensu
|
|
95
76
|
''
|
96
77
|
end
|
97
78
|
|
79
|
+
helpers do
|
80
|
+
def request_log_line
|
81
|
+
$logger.info([env['REQUEST_METHOD'], env['REQUEST_PATH']].join(' '), {
|
82
|
+
:remote_address => env['REMOTE_ADDR'],
|
83
|
+
:user_agent => env['HTTP_USER_AGENT'],
|
84
|
+
:request_method => env['REQUEST_METHOD'],
|
85
|
+
:request_uri => env['REQUEST_URI'],
|
86
|
+
:request_body => env['rack.input'].read
|
87
|
+
})
|
88
|
+
env['rack.input'].rewind
|
89
|
+
end
|
90
|
+
|
91
|
+
def health_filter
|
92
|
+
unless $redis.connected?
|
93
|
+
unless env['REQUEST_PATH'] == '/info'
|
94
|
+
halt 500
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def event_hash(event_json, client_name, check_name)
|
100
|
+
JSON.parse(event_json, :symbolize_names => true).merge(
|
101
|
+
:client => client_name,
|
102
|
+
:check => check_name
|
103
|
+
)
|
104
|
+
end
|
105
|
+
|
106
|
+
def resolve_event(client_name, check_name)
|
107
|
+
payload = {
|
108
|
+
:client => client_name,
|
109
|
+
:check => {
|
110
|
+
:name => check_name,
|
111
|
+
:output => 'Resolving on request of the API',
|
112
|
+
:status => 0,
|
113
|
+
:issued => Time.now.to_i,
|
114
|
+
:force_resolve => true
|
115
|
+
}
|
116
|
+
}
|
117
|
+
$logger.info('publishing check result', {
|
118
|
+
:payload => payload
|
119
|
+
})
|
120
|
+
$amq.queue('results').publish(payload.to_json)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
98
124
|
before do
|
99
125
|
content_type 'application/json'
|
100
|
-
|
101
|
-
|
126
|
+
request_log_line
|
127
|
+
health_filter
|
102
128
|
end
|
103
129
|
|
104
130
|
aget '/info' do
|
@@ -132,7 +158,7 @@ module Sensu
|
|
132
158
|
end
|
133
159
|
end
|
134
160
|
|
135
|
-
aget
|
161
|
+
aget %r{/clients?/([\w\.-]+)$} do |client_name|
|
136
162
|
$redis.get('client:' + client_name).callback do |client_json|
|
137
163
|
unless client_json.nil?
|
138
164
|
body client_json
|
@@ -143,31 +169,18 @@ module Sensu
|
|
143
169
|
end
|
144
170
|
end
|
145
171
|
|
146
|
-
adelete
|
172
|
+
adelete %r{/clients?/([\w\.-]+)$} do |client_name|
|
147
173
|
$redis.get('client:' + client_name).callback do |client_json|
|
148
174
|
unless client_json.nil?
|
149
|
-
client = JSON.parse(client_json, :symbolize_names => true)
|
150
|
-
$logger.info('deleting client', {
|
151
|
-
:client => client
|
152
|
-
})
|
153
175
|
$redis.hgetall('events:' + client_name).callback do |events|
|
154
176
|
events.each_key do |check_name|
|
155
|
-
|
156
|
-
:client => client_name,
|
157
|
-
:check => {
|
158
|
-
:name => check_name,
|
159
|
-
:output => 'Client is being removed on request of the API',
|
160
|
-
:status => 0,
|
161
|
-
:issued => Time.now.to_i,
|
162
|
-
:force_resolve => true
|
163
|
-
}
|
164
|
-
}
|
165
|
-
$logger.info('publishing check result', {
|
166
|
-
:payload => payload
|
167
|
-
})
|
168
|
-
$amq.queue('results').publish(payload.to_json)
|
177
|
+
resolve_event(client_name, check_name)
|
169
178
|
end
|
170
179
|
EM::Timer.new(5) do
|
180
|
+
client = JSON.parse(client_json, :symbolize_names => true)
|
181
|
+
$logger.info('deleting client', {
|
182
|
+
:client => client
|
183
|
+
})
|
171
184
|
$redis.srem('clients', client_name)
|
172
185
|
$redis.del('events:' + client_name)
|
173
186
|
$redis.del('client:' + client_name)
|
@@ -178,7 +191,7 @@ module Sensu
|
|
178
191
|
$redis.del('history:' + client_name)
|
179
192
|
end
|
180
193
|
end
|
181
|
-
status
|
194
|
+
status 202
|
182
195
|
body ''
|
183
196
|
end
|
184
197
|
else
|
@@ -192,7 +205,7 @@ module Sensu
|
|
192
205
|
body $settings.checks.to_json
|
193
206
|
end
|
194
207
|
|
195
|
-
aget
|
208
|
+
aget %r{/checks?/([\w\.-]+)$} do |check_name|
|
196
209
|
if $settings.check_exists?(check_name)
|
197
210
|
response = $settings[:checks][check_name].merge(:name => check_name)
|
198
211
|
body response.to_json
|
@@ -202,23 +215,25 @@ module Sensu
|
|
202
215
|
end
|
203
216
|
end
|
204
217
|
|
205
|
-
apost
|
218
|
+
apost %r{/(?:check/)?request$} do
|
206
219
|
begin
|
207
220
|
post_body = JSON.parse(request.body.read, :symbolize_names => true)
|
208
|
-
|
221
|
+
check_name = post_body[:check]
|
222
|
+
subscribers = post_body[:subscribers]
|
223
|
+
rescue JSON::ParserError, TypeError
|
209
224
|
status 400
|
210
225
|
body ''
|
211
226
|
end
|
212
|
-
if
|
227
|
+
if check_name.is_a?(String) && subscribers.is_a?(Array)
|
213
228
|
payload = {
|
214
|
-
:name =>
|
229
|
+
:name => check_name,
|
215
230
|
:issued => Time.now.to_i
|
216
231
|
}
|
217
232
|
$logger.info('publishing check request', {
|
218
233
|
:payload => payload,
|
219
|
-
:subscribers =>
|
234
|
+
:subscribers => subscribers
|
220
235
|
})
|
221
|
-
|
236
|
+
subscribers.uniq.each do |exchange_name|
|
222
237
|
$amq.fanout(exchange_name).publish(payload.to_json)
|
223
238
|
end
|
224
239
|
status 201
|
@@ -235,7 +250,7 @@ module Sensu
|
|
235
250
|
clients.each_with_index do |client_name, index|
|
236
251
|
$redis.hgetall('events:' + client_name).callback do |events|
|
237
252
|
events.each do |check_name, event_json|
|
238
|
-
response.push(
|
253
|
+
response.push(event_hash(event_json, client_name, check_name))
|
239
254
|
end
|
240
255
|
if index == clients.size - 1
|
241
256
|
body response.to_json
|
@@ -248,12 +263,21 @@ module Sensu
|
|
248
263
|
end
|
249
264
|
end
|
250
265
|
|
251
|
-
aget
|
266
|
+
aget %r{/events/([\w\.-]+)$} do |client_name|
|
267
|
+
response = Array.new
|
268
|
+
$redis.hgetall('events:' + client_name).callback do |events|
|
269
|
+
events.each do |check_name, event_json|
|
270
|
+
response.push(event_hash(event_json, client_name, check_name))
|
271
|
+
end
|
272
|
+
body response.to_json
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
aget %r{/events?/([\w\.-]+)/([\w\.-]+)$} do |client_name, check_name|
|
252
277
|
$redis.hgetall('events:' + client_name).callback do |events|
|
253
278
|
event_json = events[check_name]
|
254
279
|
unless event_json.nil?
|
255
|
-
|
256
|
-
body response.to_json
|
280
|
+
body event_hash(event_json, client_name, check_name).to_json
|
257
281
|
else
|
258
282
|
status 404
|
259
283
|
body ''
|
@@ -261,31 +285,32 @@ module Sensu
|
|
261
285
|
end
|
262
286
|
end
|
263
287
|
|
264
|
-
|
288
|
+
adelete %r{/events?/([\w\.-]+)/([\w\.-]+)$} do |client_name, check_name|
|
289
|
+
$redis.hgetall('events:' + client_name).callback do |events|
|
290
|
+
if events.include?(check_name)
|
291
|
+
resolve_event(client_name, check_name)
|
292
|
+
status 202
|
293
|
+
else
|
294
|
+
status 404
|
295
|
+
end
|
296
|
+
body ''
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
apost %r{/(?:event/)?resolve$} do
|
265
301
|
begin
|
266
302
|
post_body = JSON.parse(request.body.read, :symbolize_names => true)
|
267
|
-
|
303
|
+
client_name = post_body[:client]
|
304
|
+
check_name = post_body[:check]
|
305
|
+
rescue JSON::ParserError, TypeError
|
268
306
|
status 400
|
269
307
|
body ''
|
270
308
|
end
|
271
|
-
if
|
272
|
-
$redis.hgetall('events:' +
|
273
|
-
if events.include?(
|
274
|
-
|
275
|
-
|
276
|
-
:check => {
|
277
|
-
:name => post_body[:check],
|
278
|
-
:output => 'Resolving on request of the API',
|
279
|
-
:status => 0,
|
280
|
-
:issued => Time.now.to_i,
|
281
|
-
:force_resolve => true
|
282
|
-
}
|
283
|
-
}
|
284
|
-
$logger.info('publishing check result', {
|
285
|
-
:payload => payload
|
286
|
-
})
|
287
|
-
$amq.queue('results').publish(payload.to_json)
|
288
|
-
status 201
|
309
|
+
if client_name.is_a?(String) && check_name.is_a?(String)
|
310
|
+
$redis.hgetall('events:' + client_name).callback do |events|
|
311
|
+
if events.include?(check_name)
|
312
|
+
resolve_event(client_name, check_name)
|
313
|
+
status 202
|
289
314
|
else
|
290
315
|
status 404
|
291
316
|
end
|
@@ -297,7 +322,7 @@ module Sensu
|
|
297
322
|
end
|
298
323
|
end
|
299
324
|
|
300
|
-
apost
|
325
|
+
apost %r{/stash(?:es)?/(.*)} do |path|
|
301
326
|
begin
|
302
327
|
post_body = JSON.parse(request.body.read)
|
303
328
|
rescue JSON::ParserError
|
@@ -312,7 +337,7 @@ module Sensu
|
|
312
337
|
end
|
313
338
|
end
|
314
339
|
|
315
|
-
aget
|
340
|
+
aget %r{/stash(?:es)?/(.*)} do |path|
|
316
341
|
$redis.get('stash:' + path).callback do |stash_json|
|
317
342
|
if stash_json.nil?
|
318
343
|
status 404
|
@@ -323,7 +348,7 @@ module Sensu
|
|
323
348
|
end
|
324
349
|
end
|
325
350
|
|
326
|
-
adelete
|
351
|
+
adelete %r{/stash(?:es)?/(.*)} do |path|
|
327
352
|
$redis.exists('stash:' + path).callback do |stash_exists|
|
328
353
|
if stash_exists
|
329
354
|
$redis.srem('stashes', path).callback do
|
@@ -376,17 +401,17 @@ module Sensu
|
|
376
401
|
$redis.set('client:' + $settings[:client][:name], $settings[:client].to_json).callback do
|
377
402
|
$redis.sadd('clients', $settings[:client][:name]).callback do
|
378
403
|
$redis.hset('events:' + $settings[:client][:name], 'test', {
|
379
|
-
:output =>
|
404
|
+
:output => 'CRITICAL',
|
380
405
|
:status => 2,
|
381
406
|
:issued => Time.now.to_i,
|
382
407
|
:flapping => false,
|
383
408
|
:occurrences => 1
|
384
409
|
}.to_json).callback do
|
385
|
-
$redis.set('stash:test/test',
|
410
|
+
$redis.set('stash:test/test', {:key => 'value'}.to_json).callback do
|
386
411
|
$redis.sadd('stashes', 'test/test').callback do
|
387
412
|
Thin::Logging.silent = true
|
388
413
|
Thin::Server.start(self, $settings[:api][:port])
|
389
|
-
EM::
|
414
|
+
EM::Timer.new(0.5) do
|
390
415
|
block.call
|
391
416
|
end
|
392
417
|
end
|
data/lib/sensu/client.rb
CHANGED
data/lib/sensu/constants.rb
CHANGED
data/lib/sensu/redis.rb
CHANGED
@@ -12,6 +12,14 @@ module Sensu
|
|
12
12
|
@closing_connection = false
|
13
13
|
end
|
14
14
|
|
15
|
+
def setup_heartbeat
|
16
|
+
@heartbeat ||= EM::PeriodicTimer.new(10) do
|
17
|
+
if connected?
|
18
|
+
ping
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
15
23
|
def connection_completed
|
16
24
|
@connection_established = true
|
17
25
|
@connected = true
|
@@ -30,6 +38,7 @@ module Sensu
|
|
30
38
|
close_connection
|
31
39
|
end
|
32
40
|
end
|
41
|
+
setup_heartbeat
|
33
42
|
end
|
34
43
|
|
35
44
|
def reconnect!
|
data/lib/sensu/server.rb
CHANGED
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:
|
4
|
+
hash: 62196239
|
5
5
|
prerelease: true
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 9
|
9
9
|
- 7
|
10
10
|
- beta
|
11
|
-
-
|
12
|
-
version: 0.9.7.beta.
|
11
|
+
- 2
|
12
|
+
version: 0.9.7.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-08-
|
21
|
+
date: 2012-08-10 00:00:00 -07:00
|
22
22
|
default_executable:
|
23
23
|
dependencies:
|
24
24
|
- !ruby/object:Gem::Dependency
|