sensu 0.22.2-java → 0.23.0.beta-java
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +40 -0
- data/MIT-LICENSE.txt +1 -1
- data/lib/sensu/api/process.rb +69 -65
- data/lib/sensu/cli.rb +3 -0
- data/lib/sensu/client/process.rb +9 -44
- data/lib/sensu/client/socket.rb +4 -4
- data/lib/sensu/constants.rb +1 -1
- data/lib/sensu/daemon.rb +69 -40
- data/lib/sensu/server/filter.rb +63 -24
- data/lib/sensu/server/mutate.rb +1 -1
- data/lib/sensu/server/process.rb +68 -54
- data/lib/sensu/server/sandbox.rb +4 -4
- data/lib/sensu/utilities.rb +40 -4
- data/sensu.gemspec +7 -9
- metadata +21 -36
- data/lib/sensu/redis.rb +0 -25
data/lib/sensu/daemon.rb
CHANGED
@@ -1,31 +1,30 @@
|
|
1
1
|
require "rubygems"
|
2
2
|
|
3
|
-
gem "
|
4
|
-
gem "eventmachine", "1.0.9.1"
|
3
|
+
gem "eventmachine", "1.2.0.1"
|
5
4
|
|
6
|
-
gem "sensu-
|
7
|
-
gem "sensu-
|
5
|
+
gem "sensu-json", "1.1.0"
|
6
|
+
gem "sensu-logger", "1.2.0"
|
7
|
+
gem "sensu-settings", "3.4.0"
|
8
8
|
gem "sensu-extension", "1.5.0"
|
9
|
-
gem "sensu-extensions", "1.
|
10
|
-
gem "sensu-transport", "
|
9
|
+
gem "sensu-extensions", "1.5.0"
|
10
|
+
gem "sensu-transport", "5.0.0"
|
11
11
|
gem "sensu-spawn", "1.8.0"
|
12
|
+
gem "sensu-redis", "1.2.0"
|
12
13
|
|
13
14
|
require "time"
|
14
15
|
require "uri"
|
15
16
|
|
17
|
+
require "sensu/json"
|
16
18
|
require "sensu/logger"
|
17
19
|
require "sensu/settings"
|
18
20
|
require "sensu/extensions"
|
19
21
|
require "sensu/transport"
|
20
22
|
require "sensu/spawn"
|
23
|
+
require "sensu/redis"
|
21
24
|
|
22
25
|
require "sensu/constants"
|
23
26
|
require "sensu/utilities"
|
24
27
|
require "sensu/cli"
|
25
|
-
require "sensu/redis"
|
26
|
-
|
27
|
-
# Symbolize hash keys when parsing JSON.
|
28
|
-
MultiJson.load_options = {:symbolize_keys => true}
|
29
28
|
|
30
29
|
module Sensu
|
31
30
|
module Daemon
|
@@ -73,10 +72,26 @@ module Sensu
|
|
73
72
|
end
|
74
73
|
end
|
75
74
|
|
75
|
+
# Print the Sensu settings and immediately exit the process. This
|
76
|
+
# method is used while troubleshooting configuration issues,
|
77
|
+
# triggered by a CLI argument, e.g. `--print_config`. Sensu
|
78
|
+
# settings with sensitive values (e.g. passwords) are first
|
79
|
+
# redacted.
|
80
|
+
#
|
81
|
+
# @param settings [Object]
|
82
|
+
def print_settings(settings)
|
83
|
+
redacted_settings = redact_sensitive(settings.to_hash)
|
84
|
+
@logger.warn("outputting compiled configuration and exiting")
|
85
|
+
puts Sensu::JSON.dump(redacted_settings, :pretty => true)
|
86
|
+
exit
|
87
|
+
end
|
88
|
+
|
76
89
|
# Load Sensu settings and validate them. If there are validation
|
77
90
|
# failures, log them (concerns), then cause the Sensu process to
|
78
91
|
# exit (2). This method creates the settings instance variable:
|
79
|
-
# `@settings`.
|
92
|
+
# `@settings`. If the `print_config` option is true, this method
|
93
|
+
# calls `print_settings()` to output the compiled configuration
|
94
|
+
# settings and then exit the process.
|
80
95
|
#
|
81
96
|
# https://github.com/sensu/sensu-settings
|
82
97
|
#
|
@@ -91,6 +106,7 @@ module Sensu
|
|
91
106
|
@logger.fatal("SENSU NOT RUNNING!")
|
92
107
|
exit 2
|
93
108
|
end
|
109
|
+
print_settings(@settings) if options[:print_config]
|
94
110
|
end
|
95
111
|
|
96
112
|
# Load Sensu extensions and log any concerns. Set the logger and
|
@@ -176,6 +192,9 @@ module Sensu
|
|
176
192
|
# method creates the transport instance variable: `@transport`.
|
177
193
|
#
|
178
194
|
# https://github.com/sensu/sensu-transport
|
195
|
+
#
|
196
|
+
# @yield [Object] passes initialized and connected Transport
|
197
|
+
# connection object to the callback/block.
|
179
198
|
def setup_transport
|
180
199
|
transport_name = @settings[:transport][:name]
|
181
200
|
transport_settings = @settings[transport_name]
|
@@ -184,24 +203,27 @@ module Sensu
|
|
184
203
|
:settings => transport_settings
|
185
204
|
})
|
186
205
|
Transport.logger = @logger
|
187
|
-
|
188
|
-
|
189
|
-
@
|
190
|
-
|
191
|
-
@transport
|
192
|
-
|
193
|
-
|
206
|
+
Transport.connect(transport_name, transport_settings) do |connection|
|
207
|
+
@transport = connection
|
208
|
+
@transport.on_error do |error|
|
209
|
+
@logger.error("transport connection error", :error => error.to_s)
|
210
|
+
if @settings[:transport][:reconnect_on_error]
|
211
|
+
@transport.reconnect
|
212
|
+
else
|
213
|
+
stop
|
214
|
+
end
|
194
215
|
end
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
216
|
+
@transport.before_reconnect do
|
217
|
+
unless testing?
|
218
|
+
@logger.warn("reconnecting to transport")
|
219
|
+
pause
|
220
|
+
end
|
200
221
|
end
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
222
|
+
@transport.after_reconnect do
|
223
|
+
@logger.info("reconnected to transport")
|
224
|
+
resume
|
225
|
+
end
|
226
|
+
yield(@transport)
|
205
227
|
end
|
206
228
|
end
|
207
229
|
|
@@ -210,22 +232,29 @@ module Sensu
|
|
210
232
|
# service will stop gracefully in the event of a Redis error, and
|
211
233
|
# pause/resume in the event of connectivity issues. This method
|
212
234
|
# creates the Redis instance variable: `@redis`.
|
235
|
+
#
|
236
|
+
# https://github.com/sensu/sensu-redis
|
237
|
+
#
|
238
|
+
# @yield [Object] passes initialized and connected Redis
|
239
|
+
# connection object to the callback/block.
|
213
240
|
def setup_redis
|
214
241
|
@logger.debug("connecting to redis", :settings => @settings[:redis])
|
215
|
-
|
216
|
-
|
217
|
-
@
|
218
|
-
|
219
|
-
end
|
220
|
-
@redis.before_reconnect do
|
221
|
-
unless testing?
|
222
|
-
@logger.warn("reconnecting to redis")
|
223
|
-
pause
|
242
|
+
Redis.connect(@settings[:redis]) do |connection|
|
243
|
+
@redis = connection
|
244
|
+
@redis.on_error do |error|
|
245
|
+
@logger.error("redis connection error", :error => error.to_s)
|
224
246
|
end
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
247
|
+
@redis.before_reconnect do
|
248
|
+
unless testing?
|
249
|
+
@logger.warn("reconnecting to redis")
|
250
|
+
pause
|
251
|
+
end
|
252
|
+
end
|
253
|
+
@redis.after_reconnect do
|
254
|
+
@logger.info("reconnected to redis")
|
255
|
+
resume
|
256
|
+
end
|
257
|
+
yield(@redis)
|
229
258
|
end
|
230
259
|
end
|
231
260
|
|
data/lib/sensu/server/filter.rb
CHANGED
@@ -3,6 +3,8 @@ require "sensu/server/sandbox"
|
|
3
3
|
module Sensu
|
4
4
|
module Server
|
5
5
|
module Filter
|
6
|
+
EVAL_PREFIX = "eval:".freeze
|
7
|
+
|
6
8
|
# Determine if a period of time (window) is subdued. The
|
7
9
|
# provided condition must have a `:begin` and `:end` time, eg.
|
8
10
|
# "11:30:00 PM", or `false` will be returned.
|
@@ -165,28 +167,63 @@ module Sensu
|
|
165
167
|
end
|
166
168
|
end
|
167
169
|
|
168
|
-
#
|
170
|
+
# Process a filter eval attribute, a Ruby `eval()` string
|
171
|
+
# containing an expression to be evaluated within the
|
172
|
+
# scope/context of a sandbox. This methods strips away the
|
173
|
+
# expression prefix, `eval:`, and substitues any dot notation
|
174
|
+
# tokens with the corresponding event data values. If there are
|
175
|
+
# unmatched tokens, this method will return `nil`.
|
176
|
+
#
|
177
|
+
# @event [Hash]
|
178
|
+
# @raw_eval_string [String]
|
179
|
+
# @return [String] processed eval string.
|
180
|
+
def process_eval_string(event, raw_eval_string)
|
181
|
+
eval_string = raw_eval_string.slice(5..-1)
|
182
|
+
eval_string, unmatched_tokens = substitute_tokens(eval_string, event)
|
183
|
+
if unmatched_tokens.empty?
|
184
|
+
eval_string
|
185
|
+
else
|
186
|
+
@logger.error("filter eval unmatched tokens", {
|
187
|
+
:raw_eval_string => raw_eval_string,
|
188
|
+
:unmatched_tokens => unmatched_tokens,
|
189
|
+
:event => event
|
190
|
+
})
|
191
|
+
nil
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# Ruby `eval()` a string containing an expression, within the
|
169
196
|
# scope/context of a sandbox. This method is for filter
|
170
197
|
# attribute values starting with "eval:", with the Ruby
|
171
198
|
# expression following the colon. A single variable is provided
|
172
199
|
# to the expression, `value`, equal to the corresponding event
|
173
|
-
# attribute value.
|
174
|
-
#
|
200
|
+
# attribute value. Dot notation tokens in the expression, e.g.
|
201
|
+
# `:::mysql.user:::`, are substituted with the corresponding
|
202
|
+
# event data values prior to evaluation. The expression is
|
203
|
+
# expected to return a boolean value.
|
175
204
|
#
|
205
|
+
# @param event [Hash]
|
176
206
|
# @param raw_eval_string [String] containing the Ruby
|
177
207
|
# expression to be evaluated.
|
178
|
-
# @param
|
208
|
+
# @param raw_value [Object] of the corresponding event
|
209
|
+
# attribute value.
|
179
210
|
# @return [TrueClass, FalseClass]
|
180
|
-
def eval_attribute_value(raw_eval_string,
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
211
|
+
def eval_attribute_value(event, raw_eval_string, raw_value)
|
212
|
+
eval_string = process_eval_string(event, raw_eval_string)
|
213
|
+
unless eval_string.nil?
|
214
|
+
begin
|
215
|
+
value = Marshal.load(Marshal.dump(raw_value))
|
216
|
+
!!Sandbox.eval(eval_string, value)
|
217
|
+
rescue => error
|
218
|
+
@logger.error("filter attribute eval error", {
|
219
|
+
:event => event,
|
220
|
+
:raw_eval_string => raw_eval_string,
|
221
|
+
:raw_value => raw_value,
|
222
|
+
:error => error.to_s
|
223
|
+
})
|
224
|
+
false
|
225
|
+
end
|
226
|
+
else
|
190
227
|
false
|
191
228
|
end
|
192
229
|
end
|
@@ -197,21 +234,23 @@ module Sensu
|
|
197
234
|
# key/value pairs (recursive), have equal string values, or
|
198
235
|
# evaluate to true (Ruby eval).
|
199
236
|
#
|
200
|
-
# @param
|
201
|
-
# @param
|
237
|
+
# @param event [Hash]
|
238
|
+
# @param filter_attributes [Object]
|
239
|
+
# @param event_attributes [Object]
|
202
240
|
# @return [TrueClass, FalseClass]
|
203
|
-
def filter_attributes_match?(
|
204
|
-
|
205
|
-
|
241
|
+
def filter_attributes_match?(event, filter_attributes, event_attributes=nil)
|
242
|
+
event_attributes ||= event
|
243
|
+
filter_attributes.all? do |key, value_one|
|
244
|
+
value_two = event_attributes[key]
|
206
245
|
case
|
207
246
|
when value_one == value_two
|
208
247
|
true
|
209
248
|
when value_one.is_a?(Hash) && value_two.is_a?(Hash)
|
210
|
-
filter_attributes_match?(value_one, value_two)
|
211
|
-
when
|
249
|
+
filter_attributes_match?(event, value_one, value_two)
|
250
|
+
when value_one.to_s == value_two.to_s
|
212
251
|
true
|
213
|
-
when value_one.is_a?(String) && value_one.start_with?(
|
214
|
-
eval_attribute_value(value_one, value_two)
|
252
|
+
when value_one.is_a?(String) && value_one.start_with?(EVAL_PREFIX)
|
253
|
+
eval_attribute_value(event, value_one, value_two)
|
215
254
|
else
|
216
255
|
false
|
217
256
|
end
|
@@ -236,7 +275,7 @@ module Sensu
|
|
236
275
|
case
|
237
276
|
when @settings.filter_exists?(filter_name)
|
238
277
|
filter = @settings[:filters][filter_name]
|
239
|
-
matched = filter_attributes_match?(filter[:attributes]
|
278
|
+
matched = filter_attributes_match?(event, filter[:attributes])
|
240
279
|
yield(filter[:negate] ? matched : !matched)
|
241
280
|
when @extensions.filter_exists?(filter_name)
|
242
281
|
extension = @extensions[:filters][filter_name]
|
data/lib/sensu/server/mutate.rb
CHANGED
@@ -40,7 +40,7 @@ module Sensu
|
|
40
40
|
# @param callback [Proc] to call when the mutator executes
|
41
41
|
# successfully.
|
42
42
|
def pipe_mutator(mutator, event, &callback)
|
43
|
-
options = {:data =>
|
43
|
+
options = {:data => Sensu::JSON.dump(event), :timeout => mutator[:timeout]}
|
44
44
|
block = mutator_callback(mutator, event, &callback)
|
45
45
|
Spawn.process(mutator[:command], options, &block)
|
46
46
|
end
|
data/lib/sensu/server/process.rb
CHANGED
@@ -43,6 +43,20 @@ module Sensu
|
|
43
43
|
@handling_event_count = 0
|
44
44
|
end
|
45
45
|
|
46
|
+
# Set up the Redis and Transport connection objects, `@redis`
|
47
|
+
# and `@transport`. This method "drys" up many instances of
|
48
|
+
# `setup_redis()` and `setup_transport()`.
|
49
|
+
#
|
50
|
+
# @yield callback/block called after connecting to Redis and the
|
51
|
+
# Sensu Transport.
|
52
|
+
def setup_connections
|
53
|
+
setup_redis do
|
54
|
+
setup_transport do
|
55
|
+
yield
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
46
60
|
# Create a registration check definition for a client. Client
|
47
61
|
# definitions may contain `:registration` configuration,
|
48
62
|
# containing custom attributes and handler information. By
|
@@ -127,10 +141,11 @@ module Sensu
|
|
127
141
|
@redis.set(signature_key, client[:signature])
|
128
142
|
end
|
129
143
|
if signature.nil? || signature.empty? || (client[:signature] == signature)
|
130
|
-
@redis.
|
131
|
-
|
132
|
-
|
133
|
-
|
144
|
+
@redis.multi
|
145
|
+
@redis.set(client_key, Sensu::JSON.dump(client))
|
146
|
+
@redis.sadd("clients", client[:name])
|
147
|
+
@redis.exec do
|
148
|
+
yield(true) if block_given?
|
134
149
|
end
|
135
150
|
else
|
136
151
|
@logger.warn("invalid client signature", {
|
@@ -156,11 +171,11 @@ module Sensu
|
|
156
171
|
@transport.subscribe(:direct, "keepalives", "keepalives", :ack => true) do |message_info, message|
|
157
172
|
@logger.debug("received keepalive", :message => message)
|
158
173
|
begin
|
159
|
-
client =
|
174
|
+
client = Sensu::JSON.load(message)
|
160
175
|
update_client_registry(client) do
|
161
176
|
@transport.ack(message_info)
|
162
177
|
end
|
163
|
-
rescue
|
178
|
+
rescue Sensu::JSON::ParseError => error
|
164
179
|
@logger.error("failed to parse keepalive payload", {
|
165
180
|
:message => message,
|
166
181
|
:error => error.to_s
|
@@ -273,20 +288,18 @@ module Sensu
|
|
273
288
|
:check => check
|
274
289
|
})
|
275
290
|
result_set = "#{check[:name]}:#{check[:issued]}"
|
276
|
-
result_data =
|
277
|
-
@redis.
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
severity = (SEVERITIES[check[:status]] || "unknown")
|
282
|
-
@redis.hincrby("aggregate:#{result_set}", severity, 1) do
|
283
|
-
@redis.hincrby("aggregate:#{result_set}", "total", 1) do
|
284
|
-
@redis.sadd("aggregates:#{check[:name]}", check[:issued]) do
|
285
|
-
@redis.sadd("aggregates", check[:name])
|
286
|
-
end
|
287
|
-
end
|
288
|
-
end
|
291
|
+
result_data = Sensu::JSON.dump(:output => check[:output], :status => check[:status])
|
292
|
+
@redis.multi
|
293
|
+
@redis.hset("aggregation:#{result_set}", client[:name], result_data)
|
294
|
+
SEVERITIES.each do |severity|
|
295
|
+
@redis.hsetnx("aggregate:#{result_set}", severity, 0)
|
289
296
|
end
|
297
|
+
severity = (SEVERITIES[check[:status]] || "unknown")
|
298
|
+
@redis.hincrby("aggregate:#{result_set}", severity, 1)
|
299
|
+
@redis.hincrby("aggregate:#{result_set}", "total", 1)
|
300
|
+
@redis.sadd("aggregates:#{check[:name]}", check[:issued])
|
301
|
+
@redis.sadd("aggregates", check[:name])
|
302
|
+
@redis.exec
|
290
303
|
end
|
291
304
|
|
292
305
|
# Truncate check output. For metric checks, (`"type":
|
@@ -301,7 +314,7 @@ module Sensu
|
|
301
314
|
when METRIC_CHECK_TYPE
|
302
315
|
output_lines = check[:output].split("\n")
|
303
316
|
output = output_lines.first || check[:output]
|
304
|
-
if output_lines.
|
317
|
+
if output_lines.length > 1 || output.length > 255
|
305
318
|
output = output[0..255] + "\n..."
|
306
319
|
end
|
307
320
|
check.merge(:output => output)
|
@@ -323,15 +336,16 @@ module Sensu
|
|
323
336
|
# stored (history, etc).
|
324
337
|
def store_check_result(client, check)
|
325
338
|
@logger.debug("storing check result", :check => check)
|
326
|
-
@redis.sadd("result:#{client[:name]}", check[:name])
|
327
339
|
result_key = "#{client[:name]}:#{check[:name]}"
|
340
|
+
history_key = "history:#{result_key}"
|
328
341
|
check_truncated = truncate_check_output(check)
|
329
|
-
@redis.
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
342
|
+
@redis.multi
|
343
|
+
@redis.sadd("result:#{client[:name]}", check[:name])
|
344
|
+
@redis.set("result:#{result_key}", Sensu::JSON.dump(check_truncated))
|
345
|
+
@redis.rpush(history_key, check[:status])
|
346
|
+
@redis.ltrim(history_key, -21, -1)
|
347
|
+
@redis.exec do
|
348
|
+
yield
|
335
349
|
end
|
336
350
|
end
|
337
351
|
|
@@ -355,7 +369,7 @@ module Sensu
|
|
355
369
|
history_key = "history:#{client[:name]}:#{check[:name]}"
|
356
370
|
@redis.lrange(history_key, -21, -1) do |history|
|
357
371
|
total_state_change = 0
|
358
|
-
unless history.
|
372
|
+
unless history.length < 21
|
359
373
|
state_changes = 0
|
360
374
|
change_weight = 0.8
|
361
375
|
previous_status = history.first
|
@@ -427,7 +441,7 @@ module Sensu
|
|
427
441
|
# @yieldparam event [Hash]
|
428
442
|
def update_event_registry(client, check)
|
429
443
|
@redis.hget("events:#{client[:name]}", check[:name]) do |event_json|
|
430
|
-
stored_event = event_json ?
|
444
|
+
stored_event = event_json ? Sensu::JSON.load(event_json) : nil
|
431
445
|
flapping = check_flapping?(stored_event, check)
|
432
446
|
event = {
|
433
447
|
:id => random_uuid,
|
@@ -441,7 +455,7 @@ module Sensu
|
|
441
455
|
if stored_event && check[:status] == stored_event[:check][:status]
|
442
456
|
event[:occurrences] = stored_event[:occurrences] + 1
|
443
457
|
end
|
444
|
-
@redis.hset("events:#{client[:name]}", check[:name],
|
458
|
+
@redis.hset("events:#{client[:name]}", check[:name], Sensu::JSON.dump(event)) do
|
445
459
|
yield(event)
|
446
460
|
end
|
447
461
|
elsif stored_event
|
@@ -498,7 +512,7 @@ module Sensu
|
|
498
512
|
client_key = result[:check][:source] || result[:client]
|
499
513
|
@redis.get("client:#{client_key}") do |client_json|
|
500
514
|
unless client_json.nil?
|
501
|
-
client =
|
515
|
+
client = Sensu::JSON.load(client_json)
|
502
516
|
if client[:signature]
|
503
517
|
if client[:signature] == result[:signature]
|
504
518
|
yield(client)
|
@@ -563,10 +577,10 @@ module Sensu
|
|
563
577
|
@logger.debug("subscribing to results")
|
564
578
|
@transport.subscribe(:direct, "results", "results", :ack => true) do |message_info, message|
|
565
579
|
begin
|
566
|
-
result =
|
580
|
+
result = Sensu::JSON.load(message)
|
567
581
|
@logger.debug("received result", :result => result)
|
568
582
|
process_check_result(result)
|
569
|
-
rescue
|
583
|
+
rescue Sensu::JSON::ParseError => error
|
570
584
|
@logger.error("failed to parse result payload", {
|
571
585
|
:message => message,
|
572
586
|
:error => error.to_s
|
@@ -620,7 +634,7 @@ module Sensu
|
|
620
634
|
:subscribers => check[:subscribers]
|
621
635
|
})
|
622
636
|
check[:subscribers].each do |subscription|
|
623
|
-
options = transport_publish_options(subscription,
|
637
|
+
options = transport_publish_options(subscription, Sensu::JSON.dump(payload))
|
624
638
|
@transport.publish(*options) do |info|
|
625
639
|
if info[:error]
|
626
640
|
@logger.error("failed to publish check request", {
|
@@ -704,7 +718,7 @@ module Sensu
|
|
704
718
|
@redis.get("client:#{client_name}:signature") do |signature|
|
705
719
|
payload[:signature] = signature if signature
|
706
720
|
@logger.debug("publishing check result", :payload => payload)
|
707
|
-
@transport.publish(:direct, "results",
|
721
|
+
@transport.publish(:direct, "results", Sensu::JSON.dump(payload)) do |info|
|
708
722
|
if info[:error]
|
709
723
|
@logger.error("failed to publish check result", {
|
710
724
|
:payload => payload,
|
@@ -758,7 +772,7 @@ module Sensu
|
|
758
772
|
clients.each do |client_name|
|
759
773
|
@redis.get("client:#{client_name}") do |client_json|
|
760
774
|
unless client_json.nil?
|
761
|
-
client =
|
775
|
+
client = Sensu::JSON.load(client_json)
|
762
776
|
next if client[:keepalives] == false
|
763
777
|
check = create_keepalive_check(client)
|
764
778
|
time_since_last_keepalive = Time.now.to_i - client[:timestamp]
|
@@ -810,7 +824,7 @@ module Sensu
|
|
810
824
|
result_key = "#{client_name}:#{check_name}"
|
811
825
|
@redis.get("result:#{result_key}") do |result_json|
|
812
826
|
unless result_json.nil?
|
813
|
-
check =
|
827
|
+
check = Sensu::JSON.load(result_json)
|
814
828
|
next unless check[:ttl] && check[:executed] && !check[:force_resolve]
|
815
829
|
time_since_last_execution = Time.now.to_i - check[:executed]
|
816
830
|
if time_since_last_execution >= check[:ttl]
|
@@ -845,21 +859,21 @@ module Sensu
|
|
845
859
|
@redis.smembers("aggregates") do |checks|
|
846
860
|
checks.each do |check_name|
|
847
861
|
@redis.smembers("aggregates:#{check_name}") do |aggregates|
|
848
|
-
if aggregates.
|
862
|
+
if aggregates.length > 20
|
849
863
|
aggregates.sort!
|
850
|
-
aggregates.take(aggregates.
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
864
|
+
aggregates.take(aggregates.length - 20).each do |check_issued|
|
865
|
+
result_set = "#{check_name}:#{check_issued}"
|
866
|
+
@redis.multi
|
867
|
+
@redis.srem("aggregates:#{check_name}", check_issued)
|
868
|
+
@redis.del("aggregate:#{result_set}")
|
869
|
+
@redis.del("aggregation:#{result_set}")
|
870
|
+
@redis.exec do
|
871
|
+
@logger.debug("pruned aggregation", {
|
872
|
+
:check => {
|
873
|
+
:name => check_name,
|
874
|
+
:issued => check_issued
|
875
|
+
}
|
876
|
+
})
|
863
877
|
end
|
864
878
|
end
|
865
879
|
end
|
@@ -1059,9 +1073,9 @@ module Sensu
|
|
1059
1073
|
# Start the Sensu server process, connecting to Redis, the
|
1060
1074
|
# transport, and calling the `bootstrap()` method.
|
1061
1075
|
def start
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1076
|
+
setup_connections do
|
1077
|
+
bootstrap
|
1078
|
+
end
|
1065
1079
|
end
|
1066
1080
|
|
1067
1081
|
# Pause the Sensu server process, unless it is being paused or
|
data/lib/sensu/server/sandbox.rb
CHANGED
@@ -2,16 +2,16 @@ module Sensu
|
|
2
2
|
module Server
|
3
3
|
module Sandbox
|
4
4
|
# Evaluate a Ruby expression within the context of a simple
|
5
|
-
# "sandbox", a Proc in a module method.
|
6
|
-
#
|
7
|
-
# single value is provided to the
|
5
|
+
# "sandbox", a Proc in a module method. As of Ruby 2.3.0,
|
6
|
+
# `$SAFE` no longer supports levels > 1, so its use has been
|
7
|
+
# removed from this method. A single value is provided to the
|
8
|
+
# "sandbox".
|
8
9
|
#
|
9
10
|
# @param expression [String] to be evaluated.
|
10
11
|
# @param value [Object] to provide the "sandbox" with.
|
11
12
|
# @return [Object]
|
12
13
|
def self.eval(expression, value=nil)
|
13
14
|
result = Proc.new do
|
14
|
-
$SAFE = (RUBY_VERSION < "2.1.0" ? 4 : 3)
|
15
15
|
Kernel.eval(expression)
|
16
16
|
end
|
17
17
|
result.call
|
data/lib/sensu/utilities.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require "uuidtools"
|
1
|
+
require "securerandom"
|
4
2
|
|
5
3
|
module Sensu
|
6
4
|
module Utilities
|
@@ -50,7 +48,7 @@ module Sensu
|
|
50
48
|
#
|
51
49
|
# @return [String] random UUID.
|
52
50
|
def random_uuid
|
53
|
-
|
51
|
+
::SecureRandom.uuid
|
54
52
|
end
|
55
53
|
|
56
54
|
# Remove sensitive information from a hash (eg. passwords). By
|
@@ -82,5 +80,43 @@ module Sensu
|
|
82
80
|
end
|
83
81
|
hash
|
84
82
|
end
|
83
|
+
|
84
|
+
# Traverse a hash for an attribute value, with a fallback default
|
85
|
+
# value if nil.
|
86
|
+
#
|
87
|
+
# @param tree [Hash] to traverse.
|
88
|
+
# @param path [Array] of attribute keys.
|
89
|
+
# @param default [Object] value if attribute value is nil.
|
90
|
+
# @return [Object] attribute or fallback default value.
|
91
|
+
def find_attribute_value(tree, path, default)
|
92
|
+
attribute = tree[path.shift]
|
93
|
+
if attribute.is_a?(Hash)
|
94
|
+
find_attribute_value(attribute, path, default)
|
95
|
+
else
|
96
|
+
attribute.nil? ? default : attribute
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Substitute dot notation tokens (eg. :::db.name|production:::)
|
101
|
+
# with the associated definition attribute value. Tokens can
|
102
|
+
# provide a fallback default value, following a pipe.
|
103
|
+
#
|
104
|
+
# @param tokens [String]
|
105
|
+
# @param attributes [Hash]
|
106
|
+
# @return [Array] containing the string with tokens substituted
|
107
|
+
# and an array of unmatched tokens.
|
108
|
+
def substitute_tokens(tokens, attributes)
|
109
|
+
unmatched_tokens = []
|
110
|
+
substituted = tokens.gsub(/:::([^:].*?):::/) do
|
111
|
+
token, default = $1.to_s.split("|", -1)
|
112
|
+
path = token.split(".").map(&:to_sym)
|
113
|
+
matched = find_attribute_value(attributes, path, default)
|
114
|
+
if matched.nil?
|
115
|
+
unmatched_tokens << token
|
116
|
+
end
|
117
|
+
matched
|
118
|
+
end
|
119
|
+
[substituted, unmatched_tokens]
|
120
|
+
end
|
85
121
|
end
|
86
122
|
end
|
data/sensu.gemspec
CHANGED
@@ -13,17 +13,15 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.license = "MIT"
|
14
14
|
s.has_rdoc = false
|
15
15
|
|
16
|
-
s.add_dependency "
|
17
|
-
s.add_dependency "
|
18
|
-
s.add_dependency "
|
19
|
-
s.add_dependency "
|
20
|
-
s.add_dependency "sensu-logger", "1.1.0"
|
21
|
-
s.add_dependency "sensu-settings", "3.3.0"
|
16
|
+
s.add_dependency "eventmachine", "1.2.0.1"
|
17
|
+
s.add_dependency "sensu-json", "1.1.0"
|
18
|
+
s.add_dependency "sensu-logger", "1.2.0"
|
19
|
+
s.add_dependency "sensu-settings", "3.4.0"
|
22
20
|
s.add_dependency "sensu-extension", "1.5.0"
|
23
|
-
s.add_dependency "sensu-extensions", "1.
|
24
|
-
s.add_dependency "sensu-transport", "
|
21
|
+
s.add_dependency "sensu-extensions", "1.5.0"
|
22
|
+
s.add_dependency "sensu-transport", "5.0.0"
|
25
23
|
s.add_dependency "sensu-spawn", "1.8.0"
|
26
|
-
s.add_dependency "
|
24
|
+
s.add_dependency "sensu-redis", "1.2.0"
|
27
25
|
s.add_dependency "sinatra", "1.4.6"
|
28
26
|
s.add_dependency "async_sinatra", "1.2.0"
|
29
27
|
s.add_dependency "thin", "1.6.3" unless RUBY_PLATFORM =~ /java/
|