sensu 0.9.8.beta → 0.9.8.beta.1
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/lib/sensu/api.rb +11 -3
- data/lib/sensu/base.rb +2 -1
- data/lib/sensu/client.rb +8 -3
- data/lib/sensu/constants.rb +1 -1
- data/lib/sensu/logger.rb +2 -0
- data/lib/sensu/redis.rb +2 -0
- data/lib/sensu/server.rb +133 -132
- data/lib/sensu/settings.rb +1 -1
- data/sensu.gemspec +2 -2
- metadata +27 -27
data/lib/sensu/api.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'base')
|
2
2
|
require File.join(File.dirname(__FILE__), 'redis')
|
3
3
|
|
4
|
+
gem 'thin', '1.5.0'
|
5
|
+
gem 'async_sinatra', '1.0.0'
|
6
|
+
|
4
7
|
require 'thin'
|
5
8
|
require 'sinatra/async'
|
6
9
|
|
@@ -61,11 +64,16 @@ module Sensu
|
|
61
64
|
$redis.close
|
62
65
|
exit 2
|
63
66
|
end
|
64
|
-
$rabbitmq = AMQP.connect($settings[:rabbitmq],
|
67
|
+
$rabbitmq = AMQP.connect($settings[:rabbitmq], {
|
68
|
+
:on_tcp_connection_failure => connection_failure,
|
69
|
+
:on_possible_authentication_failure => connection_failure
|
70
|
+
})
|
65
71
|
$rabbitmq.logger = Sensu::NullLogger.get
|
66
72
|
$rabbitmq.on_tcp_connection_loss do |connection, settings|
|
67
|
-
|
68
|
-
|
73
|
+
unless connection.reconnecting?
|
74
|
+
$logger.warn('reconnecting to rabbitmq')
|
75
|
+
connection.periodically_reconnect(5)
|
76
|
+
end
|
69
77
|
end
|
70
78
|
$rabbitmq.on_skipped_heartbeats do
|
71
79
|
$logger.warn('skipped rabbitmq heartbeat')
|
data/lib/sensu/base.rb
CHANGED
data/lib/sensu/client.rb
CHANGED
@@ -30,11 +30,16 @@ module Sensu
|
|
30
30
|
@logger.fatal('SENSU NOT RUNNING!')
|
31
31
|
exit 2
|
32
32
|
end
|
33
|
-
@rabbitmq = AMQP.connect(@settings[:rabbitmq],
|
33
|
+
@rabbitmq = AMQP.connect(@settings[:rabbitmq], {
|
34
|
+
:on_tcp_connection_failure => connection_failure,
|
35
|
+
:on_possible_authentication_failure => connection_failure
|
36
|
+
})
|
34
37
|
@rabbitmq.logger = Sensu::NullLogger.get
|
35
38
|
@rabbitmq.on_tcp_connection_loss do |connection, settings|
|
36
|
-
|
37
|
-
|
39
|
+
unless connection.reconnecting?
|
40
|
+
@logger.warn('reconnecting to rabbitmq')
|
41
|
+
connection.periodically_reconnect(5)
|
42
|
+
end
|
38
43
|
end
|
39
44
|
@rabbitmq.on_skipped_heartbeats do
|
40
45
|
@logger.warn('skipped rabbitmq heartbeat')
|
data/lib/sensu/constants.rb
CHANGED
data/lib/sensu/logger.rb
CHANGED
data/lib/sensu/redis.rb
CHANGED
data/lib/sensu/server.rb
CHANGED
@@ -58,12 +58,17 @@ module Sensu
|
|
58
58
|
@redis.close
|
59
59
|
exit 2
|
60
60
|
end
|
61
|
-
@rabbitmq = AMQP.connect(@settings[:rabbitmq],
|
61
|
+
@rabbitmq = AMQP.connect(@settings[:rabbitmq], {
|
62
|
+
:on_tcp_connection_failure => connection_failure,
|
63
|
+
:on_possible_authentication_failure => connection_failure
|
64
|
+
})
|
62
65
|
@rabbitmq.logger = Sensu::NullLogger.get
|
63
66
|
@rabbitmq.on_tcp_connection_loss do |connection, settings|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
+
unless connection.reconnecting?
|
68
|
+
@logger.warn('reconnecting to rabbitmq')
|
69
|
+
resign_as_master do
|
70
|
+
connection.periodically_reconnect(5)
|
71
|
+
end
|
67
72
|
end
|
68
73
|
end
|
69
74
|
@rabbitmq.on_skipped_heartbeats do
|
@@ -128,94 +133,116 @@ module Sensu
|
|
128
133
|
else
|
129
134
|
['default']
|
130
135
|
end
|
131
|
-
handler_list.
|
132
|
-
if @settings.handler_exists?(handler_name) && @settings[:handlers][handler_name][:type] == 'set'
|
133
|
-
@settings[:handlers][handler_name][:handlers]
|
134
|
-
else
|
135
|
-
handler_name
|
136
|
-
end
|
137
|
-
end
|
138
|
-
handler_list.flatten!
|
139
|
-
handler_list.uniq!
|
140
|
-
handlers = handler_list.map do |handler_name|
|
136
|
+
handlers = handler_list.inject(Array.new) do |handlers, handler_name|
|
141
137
|
if @settings.handler_exists?(handler_name)
|
142
|
-
handler = @settings[:handlers][handler_name]
|
143
|
-
if handler
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
:event => event,
|
148
|
-
:handler => handler
|
149
|
-
})
|
150
|
-
next
|
151
|
-
end
|
152
|
-
end
|
153
|
-
if check_subdued?(event[:check], :handler)
|
154
|
-
@logger.info('check is subdued at handler', {
|
155
|
-
:event => event,
|
156
|
-
:handler => handler
|
157
|
-
})
|
158
|
-
next
|
138
|
+
handler = @settings[:handlers][handler_name]
|
139
|
+
if handler[:type] == 'set'
|
140
|
+
handlers + handler[:handlers]
|
141
|
+
else
|
142
|
+
handlers.push(handler)
|
159
143
|
end
|
160
|
-
handler
|
161
144
|
else
|
162
145
|
@logger.warn('unknown handler', {
|
146
|
+
:event => event,
|
163
147
|
:handler => {
|
164
148
|
:name => handler_name
|
165
149
|
}
|
166
150
|
})
|
167
|
-
|
151
|
+
end
|
152
|
+
handlers.uniq
|
153
|
+
end
|
154
|
+
event_severity = Sensu::SEVERITIES[event[:check][:status]] || 'unknown'
|
155
|
+
handlers.select do |handler|
|
156
|
+
if handler[:type] == 'set'
|
157
|
+
@logger.error('handler sets cannot be nested', {
|
158
|
+
:event => event,
|
159
|
+
:handler => handler
|
160
|
+
})
|
161
|
+
false
|
162
|
+
elsif handler.has_key?(:severities) && !handler[:severities].include?(event_severity)
|
163
|
+
@logger.debug('handler does not handle event severity', {
|
164
|
+
:event => event,
|
165
|
+
:handler => handler
|
166
|
+
})
|
167
|
+
false
|
168
|
+
elsif check_subdued?(event[:check], :handler)
|
169
|
+
@logger.info('check is subdued at handler', {
|
170
|
+
:event => event,
|
171
|
+
:handler => handler
|
172
|
+
})
|
173
|
+
false
|
174
|
+
else
|
175
|
+
true
|
168
176
|
end
|
169
177
|
end
|
170
|
-
handlers.compact
|
171
178
|
end
|
172
179
|
|
173
|
-
def
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
mutated.push(line)
|
180
|
+
def execute_command(command, data=nil, on_error=nil, &block)
|
181
|
+
execute = Proc.new do
|
182
|
+
output = ''
|
183
|
+
status = 0
|
184
|
+
begin
|
185
|
+
IO.popen(command + ' 2>&1', 'r+') do |io|
|
186
|
+
unless data.nil?
|
187
|
+
io.write(data.to_s)
|
182
188
|
end
|
183
|
-
|
184
|
-
|
189
|
+
io.close_write
|
190
|
+
output = io.read
|
191
|
+
end
|
192
|
+
status = $?.exitstatus
|
193
|
+
rescue => error
|
194
|
+
status = 2
|
195
|
+
if on_error.respond_to?(:call)
|
196
|
+
on_error.call(error)
|
185
197
|
end
|
198
|
+
end
|
199
|
+
[output, status]
|
200
|
+
end
|
201
|
+
complete = Proc.new do |output, status|
|
202
|
+
block.call(output, status)
|
203
|
+
end
|
204
|
+
EM::defer(execute, complete)
|
205
|
+
end
|
206
|
+
|
207
|
+
def mutate_event_data(mutator_name, event, &block)
|
208
|
+
case mutator_name
|
209
|
+
when nil
|
210
|
+
block.call(event.to_json)
|
211
|
+
when /^only_check_output/
|
212
|
+
mutated = case mutator_name
|
213
|
+
when /split$/
|
214
|
+
event[:check][:output].split(/\n+/)
|
186
215
|
else
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
if $?.exitstatus != 0
|
216
|
+
event[:check][:output]
|
217
|
+
end
|
218
|
+
block.call(mutated)
|
219
|
+
else
|
220
|
+
if @settings.mutator_exists?(mutator_name)
|
221
|
+
mutator = @settings[:mutators][mutator_name]
|
222
|
+
on_error = Proc.new do |error|
|
223
|
+
@logger.error('mutator error', {
|
224
|
+
:event => event,
|
225
|
+
:mutator => mutator,
|
226
|
+
:error => error.to_s
|
227
|
+
})
|
228
|
+
end
|
229
|
+
execute_command(mutator[:command], event.to_json, on_error) do |output, status|
|
230
|
+
if status != 0
|
203
231
|
@logger.warn('mutator had a non-zero exit status', {
|
204
232
|
:event => event,
|
205
233
|
:mutator => mutator
|
206
234
|
})
|
207
235
|
end
|
208
|
-
|
209
|
-
@logger.warn('unknown mutator', {
|
210
|
-
:mutator => {
|
211
|
-
:name => handler[:mutator]
|
212
|
-
}
|
213
|
-
})
|
236
|
+
block.call(output)
|
214
237
|
end
|
238
|
+
else
|
239
|
+
@logger.warn('unknown mutator', {
|
240
|
+
:event => event,
|
241
|
+
:mutator => {
|
242
|
+
:name => mutator_name
|
243
|
+
}
|
244
|
+
})
|
215
245
|
end
|
216
|
-
mutated
|
217
|
-
else
|
218
|
-
event.to_json
|
219
246
|
end
|
220
247
|
end
|
221
248
|
|
@@ -228,70 +255,50 @@ module Sensu
|
|
228
255
|
:handler => handler
|
229
256
|
})
|
230
257
|
@handlers_in_progress_count += 1
|
231
|
-
|
232
|
-
|
233
|
-
|
258
|
+
on_error = Proc.new do |error|
|
259
|
+
@logger.error('handler error', {
|
260
|
+
:event => event,
|
261
|
+
:handler => handler,
|
262
|
+
:error => error.to_s
|
263
|
+
})
|
264
|
+
@handlers_in_progress_count -= 1
|
265
|
+
end
|
266
|
+
mutate_event_data(handler[:mutator], event) do |event_data|
|
267
|
+
case handler[:type]
|
268
|
+
when 'pipe'
|
269
|
+
execute_command(handler[:command], event_data, on_error) do |output, status|
|
270
|
+
output.split(/\n+/).each do |line|
|
271
|
+
@logger.info(line)
|
272
|
+
end
|
273
|
+
@handlers_in_progress_count -= 1
|
274
|
+
end
|
275
|
+
when 'tcp'
|
234
276
|
begin
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
io.close_write
|
240
|
-
io.read.split(/\n+/).each do |line|
|
241
|
-
@logger.info(line)
|
242
|
-
end
|
243
|
-
end
|
277
|
+
EM::connect(handler[:socket][:host], handler[:socket][:port], nil) do |socket|
|
278
|
+
socket.send_data(event_data.to_s)
|
279
|
+
socket.close_connection_after_writing
|
280
|
+
@handlers_in_progress_count -= 1
|
244
281
|
end
|
245
282
|
rescue => error
|
246
|
-
|
247
|
-
:event => event,
|
248
|
-
:handler => handler,
|
249
|
-
:error => error.to_s
|
250
|
-
})
|
283
|
+
on_error.call(error)
|
251
284
|
end
|
252
|
-
|
253
|
-
complete = Proc.new do
|
254
|
-
@handlers_in_progress_count -= 1
|
255
|
-
end
|
256
|
-
EM::defer(execute, complete)
|
257
|
-
when 'tcp', 'udp'
|
258
|
-
event_data = Proc.new do
|
259
|
-
mutate_event_data(handler, event)
|
260
|
-
end
|
261
|
-
write = Proc.new do |event_data|
|
285
|
+
when 'udp'
|
262
286
|
begin
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
socket.close_connection_after_writing
|
268
|
-
end
|
269
|
-
when 'udp'
|
270
|
-
EM::open_datagram_socket('127.0.0.1', 0, nil) do |socket|
|
271
|
-
socket.send_datagram(event_data, handler[:socket][:host], handler[:socket][:port])
|
272
|
-
socket.close_connection_after_writing
|
273
|
-
end
|
287
|
+
EM::open_datagram_socket('127.0.0.1', 0, nil) do |socket|
|
288
|
+
socket.send_datagram(event_data.to_s, handler[:socket][:host], handler[:socket][:port])
|
289
|
+
socket.close_connection_after_writing
|
290
|
+
@handlers_in_progress_count -= 1
|
274
291
|
end
|
275
292
|
rescue => error
|
276
|
-
|
277
|
-
:event => event,
|
278
|
-
:handler => handler,
|
279
|
-
:error => error.to_s
|
280
|
-
})
|
293
|
+
on_error.call(error)
|
281
294
|
end
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
[:name, :type].include?(key)
|
290
|
-
end
|
291
|
-
payloads = Proc.new do
|
292
|
-
Array(mutate_event_data(handler, event))
|
293
|
-
end
|
294
|
-
publish = Proc.new do |payloads|
|
295
|
+
when 'amqp'
|
296
|
+
exchange_name = handler[:exchange][:name]
|
297
|
+
exchange_type = handler[:exchange].has_key?(:type) ? handler[:exchange][:type].to_sym : :direct
|
298
|
+
exchange_options = handler[:exchange].reject do |key, value|
|
299
|
+
[:name, :type].include?(key)
|
300
|
+
end
|
301
|
+
payloads = Array(event_data)
|
295
302
|
payloads.each do |payload|
|
296
303
|
unless payload.empty?
|
297
304
|
@amq.method(exchange_type).call(exchange_name, exchange_options).publish(payload)
|
@@ -299,12 +306,6 @@ module Sensu
|
|
299
306
|
end
|
300
307
|
@handlers_in_progress_count -= 1
|
301
308
|
end
|
302
|
-
EM::defer(payloads, publish)
|
303
|
-
when 'set'
|
304
|
-
@logger.error('handler sets cannot be nested', {
|
305
|
-
:handler => handler
|
306
|
-
})
|
307
|
-
@handlers_in_progress_count -= 1
|
308
309
|
end
|
309
310
|
end
|
310
311
|
end
|
data/lib/sensu/settings.rb
CHANGED
@@ -281,7 +281,7 @@ module Sensu
|
|
281
281
|
unless @settings[:client].is_a?(Hash)
|
282
282
|
invalid('missing client configuration')
|
283
283
|
end
|
284
|
-
unless @settings[:client][:name].is_a?(String)
|
284
|
+
unless @settings[:client][:name].is_a?(String) && !@settings[:client][:name].empty?
|
285
285
|
invalid('client must have a name')
|
286
286
|
end
|
287
287
|
unless @settings[:client][:address].is_a?(String)
|
data/sensu.gemspec
CHANGED
@@ -12,13 +12,13 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.license = 'MIT'
|
13
13
|
s.has_rdoc = false
|
14
14
|
|
15
|
-
s.add_dependency('eventmachine', '1.0.0
|
15
|
+
s.add_dependency('eventmachine', '1.0.0')
|
16
16
|
s.add_dependency('amqp', '0.9.7')
|
17
17
|
s.add_dependency('json')
|
18
18
|
s.add_dependency('cabin', '0.4.4')
|
19
19
|
s.add_dependency('ruby-redis', '0.0.2')
|
20
|
+
s.add_dependency('thin', '1.5.0')
|
20
21
|
s.add_dependency('async_sinatra', '1.0.0')
|
21
|
-
s.add_dependency('thin', '1.4.1')
|
22
22
|
|
23
23
|
s.add_development_dependency('rake')
|
24
24
|
s.add_development_dependency('em-spec')
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sensu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.8.beta
|
4
|
+
version: 0.9.8.beta.1
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,22 +10,22 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-
|
13
|
+
date: 2012-10-06 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: eventmachine
|
17
|
-
requirement: &
|
17
|
+
requirement: &5377080 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - =
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 1.0.0
|
22
|
+
version: 1.0.0
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *5377080
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: amqp
|
28
|
-
requirement: &
|
28
|
+
requirement: &5375340 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - =
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: 0.9.7
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *5375340
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: json
|
39
|
-
requirement: &
|
39
|
+
requirement: &5374380 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ! '>='
|
@@ -44,10 +44,10 @@ dependencies:
|
|
44
44
|
version: '0'
|
45
45
|
type: :runtime
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *5374380
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: cabin
|
50
|
-
requirement: &
|
50
|
+
requirement: &5371840 !ruby/object:Gem::Requirement
|
51
51
|
none: false
|
52
52
|
requirements:
|
53
53
|
- - =
|
@@ -55,10 +55,10 @@ dependencies:
|
|
55
55
|
version: 0.4.4
|
56
56
|
type: :runtime
|
57
57
|
prerelease: false
|
58
|
-
version_requirements: *
|
58
|
+
version_requirements: *5371840
|
59
59
|
- !ruby/object:Gem::Dependency
|
60
60
|
name: ruby-redis
|
61
|
-
requirement: &
|
61
|
+
requirement: &5368960 !ruby/object:Gem::Requirement
|
62
62
|
none: false
|
63
63
|
requirements:
|
64
64
|
- - =
|
@@ -66,32 +66,32 @@ dependencies:
|
|
66
66
|
version: 0.0.2
|
67
67
|
type: :runtime
|
68
68
|
prerelease: false
|
69
|
-
version_requirements: *
|
69
|
+
version_requirements: *5368960
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
|
-
name:
|
72
|
-
requirement: &
|
71
|
+
name: thin
|
72
|
+
requirement: &5367040 !ruby/object:Gem::Requirement
|
73
73
|
none: false
|
74
74
|
requirements:
|
75
75
|
- - =
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: 1.
|
77
|
+
version: 1.5.0
|
78
78
|
type: :runtime
|
79
79
|
prerelease: false
|
80
|
-
version_requirements: *
|
80
|
+
version_requirements: *5367040
|
81
81
|
- !ruby/object:Gem::Dependency
|
82
|
-
name:
|
83
|
-
requirement: &
|
82
|
+
name: async_sinatra
|
83
|
+
requirement: &5365940 !ruby/object:Gem::Requirement
|
84
84
|
none: false
|
85
85
|
requirements:
|
86
86
|
- - =
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version: 1.
|
88
|
+
version: 1.0.0
|
89
89
|
type: :runtime
|
90
90
|
prerelease: false
|
91
|
-
version_requirements: *
|
91
|
+
version_requirements: *5365940
|
92
92
|
- !ruby/object:Gem::Dependency
|
93
93
|
name: rake
|
94
|
-
requirement: &
|
94
|
+
requirement: &5365200 !ruby/object:Gem::Requirement
|
95
95
|
none: false
|
96
96
|
requirements:
|
97
97
|
- - ! '>='
|
@@ -99,10 +99,10 @@ dependencies:
|
|
99
99
|
version: '0'
|
100
100
|
type: :development
|
101
101
|
prerelease: false
|
102
|
-
version_requirements: *
|
102
|
+
version_requirements: *5365200
|
103
103
|
- !ruby/object:Gem::Dependency
|
104
104
|
name: em-spec
|
105
|
-
requirement: &
|
105
|
+
requirement: &5364600 !ruby/object:Gem::Requirement
|
106
106
|
none: false
|
107
107
|
requirements:
|
108
108
|
- - ! '>='
|
@@ -110,10 +110,10 @@ dependencies:
|
|
110
110
|
version: '0'
|
111
111
|
type: :development
|
112
112
|
prerelease: false
|
113
|
-
version_requirements: *
|
113
|
+
version_requirements: *5364600
|
114
114
|
- !ruby/object:Gem::Dependency
|
115
115
|
name: em-http-request
|
116
|
-
requirement: &
|
116
|
+
requirement: &5364040 !ruby/object:Gem::Requirement
|
117
117
|
none: false
|
118
118
|
requirements:
|
119
119
|
- - ! '>='
|
@@ -121,7 +121,7 @@ dependencies:
|
|
121
121
|
version: '0'
|
122
122
|
type: :development
|
123
123
|
prerelease: false
|
124
|
-
version_requirements: *
|
124
|
+
version_requirements: *5364040
|
125
125
|
description: A monitoring framework that aims to be simple, malleable, and scalable.
|
126
126
|
Uses the publish/subscribe model.
|
127
127
|
email:
|