sensu 0.17.2-java → 0.18.0.beta.1-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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 522c29de590fd364e34192fd4094e14c2b5b6e9c
4
- data.tar.gz: b3288099fa21bb8ecaaa2ee8ce3e2d499b66fda7
3
+ metadata.gz: bdc41be10ee3b0602db3b6152537609e702da877
4
+ data.tar.gz: 51e6b5517e0f7cbceccce322c6a51ee32d8de425
5
5
  SHA512:
6
- metadata.gz: 41de9b5dd4f14b50b9dcefe87f2519922852a357465dcf472953dac22ca40c156fa999e93832c69c7092146a919040e3956714e57374b071de49e7969f255977
7
- data.tar.gz: 26331f426dfe948a9a2a8b92b8afbf9bf2db305fa1eb21f00259287193264117df0c015762f9a20bfc20cd0dece3e7f506463e03e0003a3edacb415a02d4b197
6
+ metadata.gz: d5f7d0f1224a44a79a79101719e8a3e3d1dd65550972dd49e611bd5f98b498c5d0a4eb62788c1829ce9da41305defa1549ce29459ceb568c3bfbbb24312996df
7
+ data.tar.gz: 78952b016c084d464dc4dc323fbb393ec820a25fdaa11cda7ba5d2bf8c5971ead2c1a5bf3530547ea0bf70f354a3f1ed3661a8397e314784239840ba6246f631
data/CHANGELOG.md CHANGED
@@ -1,3 +1,33 @@
1
+ ## 0.18.0 - TBD
2
+
3
+ ### Features
4
+
5
+ Dynamic (or JIT) client creation (in the registry) for check results for a
6
+ nonexistent client or a check source. Sensu clients can now monitor an
7
+ external resource on its behalf, using a check `source` to create a JIT
8
+ client for the resource, used to store the execution history and provide
9
+ context within event data. JIT client data in the registry can be
10
+ managed/updated via the Sensu API, POST `/clients`.
11
+
12
+ Storing the latest check result for every client/check pair. This data is
13
+ currently exposed via the API at `/clients/:client/history` and will be
14
+ used by several upcoming features.
15
+
16
+ The Sensu API now listens on TCP port `4567` by default.
17
+
18
+ Sensu server leader election lock timestamps now include milliseconds to
19
+ reduce the chance of a conflict when attempting to elect a new leader.
20
+
21
+ ### Other
22
+
23
+ The Sensu client sockets (TCP/UDP) are now stopped/closed before the
24
+ process is stopped.
25
+
26
+ Sensu server "master" election is now "leader" election.
27
+
28
+ Configuration file encoding is now forced to 8-bit ASCII and UTF-8 BOMs
29
+ are removed if present.
30
+
1
31
  ## 0.17.2 - 2015-04-08
2
32
 
3
33
  ### Other
@@ -40,7 +40,7 @@ module Sensu
40
40
  setup_logger(options)
41
41
  set :logger, @logger
42
42
  load_settings(options)
43
- set :api, @settings[:api]
43
+ set :api, @settings[:api] || {}
44
44
  set :checks, @settings[:checks]
45
45
  set :all_checks, @settings.checks
46
46
  set :cors, @settings[:cors] || {
@@ -55,8 +55,13 @@ module Sensu
55
55
 
56
56
  def start_server
57
57
  Thin::Logging.silent = true
58
- bind = @settings[:api][:bind] || "0.0.0.0"
59
- @thin = Thin::Server.new(bind, @settings[:api][:port], self)
58
+ bind = settings.api[:bind] || "0.0.0.0"
59
+ port = settings.api[:port] || 4567
60
+ @logger.info("api listening", {
61
+ :bind => bind,
62
+ :port => port
63
+ })
64
+ @thin = Thin::Server.new(bind, port, self)
60
65
  @thin.start
61
66
  end
62
67
 
@@ -170,7 +175,9 @@ module Sensu
170
175
  begin
171
176
  data = MultiJson.load(env["rack.input"].read)
172
177
  valid = rules.all? do |key, rule|
173
- data[key].is_a?(rule[:type]) || (rule[:nil_ok] && data[key].nil?)
178
+ value = data[key]
179
+ (value.is_a?(rule[:type]) || (rule[:nil_ok] && value.nil?)) &&
180
+ rule[:regex].nil? || (rule[:regex] && (value =~ rule[:regex]) == 0)
174
181
  end
175
182
  if valid
176
183
  callback.call(data)
@@ -302,6 +309,23 @@ module Sensu
302
309
  end
303
310
  end
304
311
 
312
+ apost "/clients/?" do
313
+ rules = {
314
+ :name => {:type => String, :nil_ok => false, :regex => /^[\w\.-]+$/},
315
+ :address => {:type => String, :nil_ok => false},
316
+ :subscriptions => {:type => Array, :nil_ok => false}
317
+ }
318
+ read_data(rules) do |data|
319
+ data[:keepalives] = false
320
+ data[:timestamp] = Time.now.to_i
321
+ settings.redis.set("client:#{data[:name]}", MultiJson.dump(data)) do
322
+ settings.redis.sadd("clients", data[:name]) do
323
+ created!(MultiJson.dump(:name => data[:name]))
324
+ end
325
+ end
326
+ end
327
+ end
328
+
305
329
  aget "/clients/?" do
306
330
  response = Array.new
307
331
  settings.redis.smembers("clients") do |clients|
@@ -333,22 +357,25 @@ module Sensu
333
357
 
334
358
  aget %r{/clients/([\w\.-]+)/history/?$} do |client_name|
335
359
  response = Array.new
336
- settings.redis.smembers("history:#{client_name}") do |checks|
360
+ settings.redis.smembers("result:#{client_name}") do |checks|
337
361
  unless checks.empty?
338
362
  checks.each_with_index do |check_name, index|
339
- history_key = "history:#{client_name}:#{check_name}"
363
+ result_key = "#{client_name}:#{check_name}"
364
+ history_key = "history:#{result_key}"
340
365
  settings.redis.lrange(history_key, -21, -1) do |history|
341
366
  history.map! do |status|
342
367
  status.to_i
343
368
  end
344
- execution_key = "execution:#{client_name}:#{check_name}"
345
- settings.redis.get(execution_key) do |last_execution|
369
+ settings.redis.get("result:#{result_key}") do |result_json|
370
+ result = MultiJson.load(result_json)
371
+ last_execution = result[:executed]
346
372
  unless history.empty? || last_execution.nil?
347
373
  item = {
348
374
  :check => check_name,
349
375
  :history => history,
350
376
  :last_execution => last_execution.to_i,
351
- :last_status => history.last
377
+ :last_status => history.last,
378
+ :last_result => result
352
379
  }
353
380
  response << item
354
381
  end
@@ -373,18 +400,17 @@ module Sensu
373
400
  end
374
401
  EM::Timer.new(5) do
375
402
  client = MultiJson.load(client_json)
376
- settings.logger.info("deleting client", {
377
- :client => client
378
- })
403
+ settings.logger.info("deleting client", :client => client)
379
404
  settings.redis.srem("clients", client_name) do
380
405
  settings.redis.del("client:#{client_name}")
381
406
  settings.redis.del("events:#{client_name}")
382
- settings.redis.smembers("history:#{client_name}") do |checks|
407
+ settings.redis.smembers("result:#{client_name}") do |checks|
383
408
  checks.each do |check_name|
384
- settings.redis.del("history:#{client_name}:#{check_name}")
385
- settings.redis.del("execution:#{client_name}:#{check_name}")
409
+ result_key = "#{client_name}:#{check_name}"
410
+ settings.redis.del("result:#{result_key}")
411
+ settings.redis.del("history:#{result_key}")
386
412
  end
387
- settings.redis.del("history:#{client_name}")
413
+ settings.redis.del("result:#{client_name}")
388
414
  end
389
415
  end
390
416
  end
@@ -428,7 +454,7 @@ module Sensu
428
454
  :subscribers => subscribers
429
455
  })
430
456
  subscribers.uniq.each do |exchange_name|
431
- settings.transport.publish(:fanout, exchange_name, MultiJson.dump(payload)) do |info|
457
+ settings.transport.publish(:fanout, exchange_name.to_s, MultiJson.dump(payload)) do |info|
432
458
  if info[:error]
433
459
  settings.logger.error("failed to publish check request", {
434
460
  :exchange_name => exchange_name,
@@ -22,13 +22,14 @@ module Sensu
22
22
  end
23
23
 
24
24
  # Override Daemon initialize() to support Sensu client check
25
- # execution safe mode and checks in progress.
25
+ # execution safe mode, checks in progress, and open sockets.
26
26
  #
27
27
  # @param options [Hash]
28
28
  def initialize(options={})
29
29
  super
30
30
  @safe_mode = @settings[:client][:safe_mode] || false
31
31
  @checks_in_progress = []
32
+ @sockets = []
32
33
  end
33
34
 
34
35
  # Create a Sensu client keepalive payload, to be sent over the
@@ -315,18 +316,21 @@ module Sensu
315
316
  # TCP & UDP port 3030. The socket can be configured via the
316
317
  # client definition, `:socket` with `:bind` and `:port`. The
317
318
  # current instance of the Sensu logger, settings, and transport
318
- # are passed to the socket handler, `Sensu::Client::Socket`.
319
+ # are passed to the socket handler, `Sensu::Client::Socket`. The
320
+ # TCP socket server signature (Fixnum) and UDP connection object
321
+ # are stored in `@sockets`, so that they can be managed
322
+ # elsewhere, eg. `close_sockets()`.
319
323
  def setup_sockets
320
324
  options = @settings[:client][:socket] || Hash.new
321
325
  options[:bind] ||= "127.0.0.1"
322
326
  options[:port] ||= 3030
323
327
  @logger.debug("binding client tcp and udp sockets", :options => options)
324
- EM::start_server(options[:bind], options[:port], Socket) do |socket|
328
+ @sockets << EM::start_server(options[:bind], options[:port], Socket) do |socket|
325
329
  socket.logger = @logger
326
330
  socket.settings = @settings
327
331
  socket.transport = @transport
328
332
  end
329
- EM::open_datagram_socket(options[:bind], options[:port], Socket) do |socket|
333
+ @sockets << EM::open_datagram_socket(options[:bind], options[:port], Socket) do |socket|
330
334
  socket.logger = @logger
331
335
  socket.settings = @settings
332
336
  socket.transport = @transport
@@ -352,6 +356,23 @@ module Sensu
352
356
  end
353
357
  end
354
358
 
359
+ # Close the Sensu client TCP and UDP sockets. This method
360
+ # iterates through `@sockets`, which contains socket server
361
+ # signatures (Fixnum) and connection objects. A signature
362
+ # indicates a TCP socket server that needs to be stopped. A
363
+ # connection object indicates a socket connection that needs to
364
+ # be closed, eg. a UDP datagram socket.
365
+ def close_sockets
366
+ @logger.info("closing client tcp and udp sockets")
367
+ @sockets.each do |socket|
368
+ if socket.is_a?(Numeric)
369
+ EM.stop_server(socket)
370
+ else
371
+ socket.close_connection
372
+ end
373
+ end
374
+ end
375
+
355
376
  # Bootstrap the Sensu client, setting up client keepalives,
356
377
  # subscriptions, and standalone check executions. This method
357
378
  # sets the process/daemon `@state` to `:running`.
@@ -415,6 +436,7 @@ module Sensu
415
436
  pause
416
437
  @state = :stopping
417
438
  complete_checks_in_progress do
439
+ close_sockets
418
440
  @transport.close
419
441
  super
420
442
  end
@@ -1,7 +1,7 @@
1
1
  module Sensu
2
2
  unless defined?(Sensu::VERSION)
3
3
  # Sensu release version.
4
- VERSION = "0.17.2"
4
+ VERSION = "0.18.0.beta.1"
5
5
 
6
6
  # Sensu check severities.
7
7
  SEVERITIES = %w[ok warning critical unknown]
data/lib/sensu/daemon.rb CHANGED
@@ -4,7 +4,7 @@ gem "multi_json", "1.11.0"
4
4
 
5
5
  gem "sensu-em", "2.4.1"
6
6
  gem "sensu-logger", "1.0.0"
7
- gem "sensu-settings", "1.3.0"
7
+ gem "sensu-settings", "1.7.0"
8
8
  gem "sensu-extension", "1.1.2"
9
9
  gem "sensu-extensions", "1.2.0"
10
10
  gem "sensu-transport", "2.4.0"
@@ -11,7 +11,7 @@ module Sensu
11
11
  include Mutate
12
12
  include Handle
13
13
 
14
- attr_reader :is_master, :handling_event_count
14
+ attr_reader :is_leader, :handling_event_count
15
15
 
16
16
  # Create an instance of the Sensu server process, start the
17
17
  # server within the EventMachine event loop, and set up server
@@ -26,14 +26,14 @@ module Sensu
26
26
  end
27
27
  end
28
28
 
29
- # Override Daemon initialize() to support Sensu server master
29
+ # Override Daemon initialize() to support Sensu server leader
30
30
  # election and the handling event count.
31
31
  #
32
32
  # @param options [Hash]
33
33
  def initialize(options={})
34
34
  super
35
- @is_master = false
36
- @timers[:master] = Array.new
35
+ @is_leader = false
36
+ @timers[:leader] = Array.new
37
37
  @handling_event_count = 0
38
38
  end
39
39
 
@@ -49,7 +49,7 @@ module Sensu
49
49
  @logger.debug("updating client registry", :client => client)
50
50
  @redis.set("client:#{client[:name]}", MultiJson.dump(client)) do
51
51
  @redis.sadd("clients", client[:name]) do
52
- callback.call
52
+ callback.call(client)
53
53
  end
54
54
  end
55
55
  end
@@ -178,13 +178,16 @@ module Sensu
178
178
  # check execution across a number of Sensu clients. JSON
179
179
  # serialization is used for storing check result data.
180
180
  #
181
- # @param result [Hash]
182
- def aggregate_check_result(result)
183
- @logger.debug("adding check result to aggregate", :result => result)
184
- check = result[:check]
181
+ # @param client [Hash]
182
+ # @param check [Hash]
183
+ def aggregate_check_result(client, check)
184
+ @logger.debug("adding check result to aggregate", {
185
+ :client => client,
186
+ :check => check
187
+ })
185
188
  result_set = "#{check[:name]}:#{check[:issued]}"
186
189
  result_data = MultiJson.dump(:output => check[:output], :status => check[:status])
187
- @redis.hset("aggregation:#{result_set}", result[:client], result_data) do
190
+ @redis.hset("aggregation:#{result_set}", client[:name], result_data) do
188
191
  SEVERITIES.each do |severity|
189
192
  @redis.hsetnx("aggregate:#{result_set}", severity, 0)
190
193
  end
@@ -199,31 +202,34 @@ module Sensu
199
202
  end
200
203
  end
201
204
 
202
- # Store check result data. This method stores the 21 most recent
203
- # check result statuses for a client/check pair, this history
204
- # is used for event context and flap detection. The check
205
- # execution timestamp is also stored, to provide an indication
206
- # of how recent the data is.
205
+ # Store check result data. This method stores check result data
206
+ # and the 21 most recent check result statuses for a client/check
207
+ # pair, this history is used for event context and flap detection.
208
+ # The check execution timestamp is also stored, to provide an
209
+ # indication of how recent the data is.
207
210
  #
208
211
  # @param client [Hash]
209
212
  # @param check [Hash]
210
213
  # @param callback [Proc] to call when the check result data has
211
214
  # been stored (history, etc).
212
215
  def store_check_result(client, check, &callback)
213
- @redis.sadd("history:#{client[:name]}", check[:name])
216
+ @logger.debug("storing check result", :check => check)
217
+ @redis.sadd("result:#{client[:name]}", check[:name])
214
218
  result_key = "#{client[:name]}:#{check[:name]}"
215
- history_key = "history:#{result_key}"
216
- @redis.rpush(history_key, check[:status]) do
217
- @redis.set("execution:#{result_key}", check[:executed])
218
- @redis.ltrim(history_key, -21, -1)
219
- callback.call
219
+ check_truncated = check.merge(:output => check[:output][0..256])
220
+ @redis.set("result:#{result_key}", MultiJson.dump(check_truncated)) do
221
+ history_key = "history:#{result_key}"
222
+ @redis.rpush(history_key, check[:status]) do
223
+ @redis.ltrim(history_key, -21, -1)
224
+ callback.call
225
+ end
220
226
  end
221
227
  end
222
228
 
223
229
  # Fetch the execution history for a client/check pair, the 21
224
230
  # most recent check result statuses. This method also calculates
225
231
  # the total state change percentage for the history, this value
226
- # is use for check state flat detection, using a similar
232
+ # is use for check state flap detection, using a similar
227
233
  # algorithm to Nagios:
228
234
  # http://nagios.sourceforge.net/docs/3_0/flapping.html
229
235
  #
@@ -332,39 +338,73 @@ module Sensu
332
338
  end
333
339
  end
334
340
 
341
+ # Create a blank client (data) and add it to the client
342
+ # registry. Only the client name is known, the other client
343
+ # attributes must be updated via the API (POST /clients:client).
344
+ # Dynamically created clients and those updated via the API will
345
+ # have client keepalives disabled, `:keepalives` is set to
346
+ # `false`.
347
+ #
348
+ # @param name [Hash] to use for the client.
349
+ # @param callback [Proc] to be called with the dynamically
350
+ # created client data.
351
+ def create_client(name, &callback)
352
+ client = {
353
+ :name => name,
354
+ :address => "unknown",
355
+ :subscriptions => [],
356
+ :keepalives => false
357
+ }
358
+ update_client_registry(client, &callback)
359
+ end
360
+
361
+ # Retrieve a client (data) from Redis if it exists. If a client
362
+ # does not already exist, create one (a blank) using the
363
+ # `client_key` as the client name. Dynamically create client
364
+ # data can be updated using the API (POST /clients/:client).
365
+ #
366
+ # @param result [Hash] data.
367
+ # @param callback [Proc] to be called with client data, either
368
+ # retrieved from Redis, or dynamically created.
369
+ def retrieve_client(result, &callback)
370
+ client_key = result[:check][:source] || result[:client]
371
+ @redis.get("client:#{client_key}") do |client_json|
372
+ unless client_json.nil?
373
+ client = MultiJson.load(client_json)
374
+ callback.call(client)
375
+ else
376
+ create_client(client_key, &callback)
377
+ end
378
+ end
379
+ end
380
+
335
381
  # Process a check result, storing its data, inspecting its
336
382
  # contents, and taking the appropriate actions (eg. update the
337
383
  # event registry). A check result must have a valid client name,
338
- # associated with a client in the registry. Results without a
339
- # valid client are discarded, to keep the system "correct". If a
340
- # local check definition exists for the check name, and the
341
- # check result is not from a standalone check execution, it's
342
- # merged with the check result for more context.
384
+ # associated with a client in the registry or one will be
385
+ # created. If a local check definition exists for the check
386
+ # name, and the check result is not from a standalone check
387
+ # execution, it's merged with the check result for more context.
343
388
  #
344
389
  # @param result [Hash] data.
345
390
  def process_check_result(result)
346
391
  @logger.debug("processing result", :result => result)
347
- @redis.get("client:#{result[:client]}") do |client_json|
348
- unless client_json.nil?
349
- client = MultiJson.load(client_json)
350
- check = case
351
- when @settings.check_exists?(result[:check][:name]) && !result[:check][:standalone]
352
- @settings[:checks][result[:check][:name]].merge(result[:check])
353
- else
354
- result[:check]
355
- end
356
- aggregate_check_result(result) if check[:aggregate]
357
- store_check_result(client, check) do
358
- check_history(client, check) do |history, total_state_change|
359
- check[:history] = history
360
- check[:total_state_change] = total_state_change
361
- update_event_registry(client, check) do |event|
362
- process_event(event)
363
- end
392
+ retrieve_client(result) do |client|
393
+ check = case
394
+ when @settings.check_exists?(result[:check][:name]) && !result[:check][:standalone]
395
+ @settings[:checks][result[:check][:name]].merge(result[:check])
396
+ else
397
+ result[:check]
398
+ end
399
+ aggregate_check_result(client, check) if check[:aggregate]
400
+ store_check_result(client, check) do
401
+ check_history(client, check) do |history, total_state_change|
402
+ check[:history] = history
403
+ check[:total_state_change] = total_state_change
404
+ update_event_registry(client, check) do |event|
405
+ process_event(event)
364
406
  end
365
407
  end
366
- else
367
- @logger.warn("client not in registry", :client => result[:client])
368
408
  end
369
409
  end
370
410
  end
@@ -441,8 +481,8 @@ module Sensu
441
481
 
442
482
  # Schedule check executions, using EventMachine periodic timers,
443
483
  # using a calculated execution splay. The timers are stored in
444
- # the timers hash under `:master`, as check request publishing
445
- # is a task for only the Sensu server master, so they can be
484
+ # the timers hash under `:leader`, as check request publishing
485
+ # is a task for only the Sensu server leader, so they can be
446
486
  # cancelled etc. Check requests are not published if subdued.
447
487
  #
448
488
  # @param checks [Array] of definitions.
@@ -457,9 +497,9 @@ module Sensu
457
497
  end
458
498
  execution_splay = testing? ? 0 : calculate_check_execution_splay(check)
459
499
  interval = testing? ? 0.5 : check[:interval]
460
- @timers[:master] << EM::Timer.new(execution_splay) do
500
+ @timers[:leader] << EM::Timer.new(execution_splay) do
461
501
  create_check_request.call
462
- @timers[:master] << EM::PeriodicTimer.new(interval, &create_check_request)
502
+ @timers[:leader] << EM::PeriodicTimer.new(interval, &create_check_request)
463
503
  end
464
504
  end
465
505
  end
@@ -549,6 +589,7 @@ module Sensu
549
589
  @redis.get("client:#{client_name}") do |client_json|
550
590
  unless client_json.nil?
551
591
  client = MultiJson.load(client_json)
592
+ next if client[:keepalives] == false
552
593
  check = create_keepalive_check(client)
553
594
  time_since_last_keepalive = Time.now.to_i - client[:timestamp]
554
595
  check[:output] = "No keepalive sent from client for "
@@ -574,10 +615,10 @@ module Sensu
574
615
 
575
616
  # Set up the client monitor, a periodic timer to run
576
617
  # `determine_stale_clients()` every 30 seconds. The timer is
577
- # stored in the timers hash under `:master`.
618
+ # stored in the timers hash under `:leader`.
578
619
  def setup_client_monitor
579
620
  @logger.debug("monitoring client keepalives")
580
- @timers[:master] << EM::PeriodicTimer.new(30) do
621
+ @timers[:leader] << EM::PeriodicTimer.new(30) do
581
622
  determine_stale_clients
582
623
  end
583
624
  end
@@ -616,52 +657,53 @@ module Sensu
616
657
  # Set up the check result aggregation pruner, using periodic
617
658
  # timer to run `prune_check_result_aggregations()` every 20
618
659
  # seconds. The timer is stored in the timers hash under
619
- # `:master`.
660
+ # `:leader`.
620
661
  def setup_check_result_aggregation_pruner
621
662
  @logger.debug("pruning check result aggregations")
622
- @timers[:master] << EM::PeriodicTimer.new(20) do
663
+ @timers[:leader] << EM::PeriodicTimer.new(20) do
623
664
  prune_check_result_aggregations
624
665
  end
625
666
  end
626
667
 
627
- # Set up the master duties, tasks only performed by a single
668
+ # Set up the leader duties, tasks only performed by a single
628
669
  # Sensu server at a time. The duties include publishing check
629
670
  # requests, monitoring for stale clients, and pruning check
630
671
  # result aggregations.
631
- def master_duties
672
+ def leader_duties
632
673
  setup_check_request_publisher
633
674
  setup_client_monitor
634
675
  setup_check_result_aggregation_pruner
635
676
  end
636
677
 
637
- # Request a master election, a process to determine if the
638
- # current process is the master Sensu server, with its
678
+ # Request a leader election, a process to determine if the
679
+ # current process is the leader Sensu server, with its
639
680
  # own/unique duties. A Redis key/value is used as a central
640
681
  # lock, using the "SETNX" Redis command to set the key/value if
641
682
  # it does not exist, using a timestamp for the value. If the
642
683
  # current process was able to create the key/value, it is the
643
- # master, and must do the duties of the master. If the current
684
+ # leader, and must do the duties of the leader. If the current
644
685
  # process was not able to create the key/value, but the current
645
686
  # timestamp value is equal to or over 30 seconds ago, the
646
687
  # "GETSET" Redis command is used to set a new timestamp and
647
688
  # fetch the previous value to compare them, to determine if it
648
689
  # was set by the current process. If the current process is able
649
- # to set the timestamp value, it becomes the master. The master
650
- # has `@is_master` set to `true`.
651
- def request_master_election
652
- @redis.setnx("lock:master", Time.now.to_i) do |created|
690
+ # to set the timestamp value, it becomes the leader. The leader
691
+ # has `@is_leader` set to `true`.
692
+ def request_leader_election
693
+ @redis.setnx("lock:leader", Time.now.to_i) do |created|
653
694
  if created
654
- @is_master = true
655
- @logger.info("i am the master")
656
- master_duties
695
+ @is_leader = true
696
+ @logger.info("i am the leader")
697
+ leader_duties
657
698
  else
658
- @redis.get("lock:master") do |timestamp|
659
- if Time.now.to_i - timestamp.to_i >= 30
660
- @redis.getset("lock:master", Time.now.to_i) do |previous|
661
- if previous == timestamp
662
- @is_master = true
663
- @logger.info("i am now the master")
664
- master_duties
699
+ @redis.get("lock:leader") do |current_timestamp|
700
+ lock_timestamp = (Time.now.to_f * 1000).to_i
701
+ if lock_timestamp - current_timestamp.to_i >= 30000
702
+ @redis.getset("lock:leader", lock_timestamp) do |previous_timestamp|
703
+ if previous_timestamp == current_timestamp
704
+ @is_leader = true
705
+ @logger.info("i am now the leader")
706
+ leader_duties
665
707
  end
666
708
  end
667
709
  end
@@ -670,41 +712,42 @@ module Sensu
670
712
  end
671
713
  end
672
714
 
673
- # Set up the master monitor. A one-time timer is used to run
674
- # `request_master_exection()` in 2 seconds. A periodic timer is
675
- # used to update the master lock timestamp if the current
676
- # process is the master, or to run `request_master_election(),
715
+ # Set up the leader monitor. A one-time timer is used to run
716
+ # `request_leader_exection()` in 2 seconds. A periodic timer is
717
+ # used to update the leader lock timestamp if the current
718
+ # process is the leader, or to run `request_leader_election(),
677
719
  # every 10 seconds. The timers are stored in the timers hash
678
720
  # under `:run`.
679
- def setup_master_monitor
721
+ def setup_leader_monitor
680
722
  @timers[:run] << EM::Timer.new(2) do
681
- request_master_election
723
+ request_leader_election
682
724
  end
683
725
  @timers[:run] << EM::PeriodicTimer.new(10) do
684
- if @is_master
685
- @redis.set("lock:master", Time.now.to_i) do
686
- @logger.debug("updated master lock timestamp")
726
+ if @is_leader
727
+ lock_timestamp = (Time.now.to_f * 1000).to_i
728
+ @redis.set("lock:leader", lock_timestamp) do
729
+ @logger.debug("updated leader lock timestamp")
687
730
  end
688
731
  else
689
- request_master_election
732
+ request_leader_election
690
733
  end
691
734
  end
692
735
  end
693
736
 
694
- # Resign as master, if the current process is the Sensu server
695
- # master. This method cancels and clears the master timers,
737
+ # Resign as leader, if the current process is the Sensu server
738
+ # leader. This method cancels and clears the leader timers,
696
739
  # those with references stored in the timers hash under
697
- # `:master`, and `@is_master`is set to `false`.
698
- def resign_as_master
699
- if @is_master
700
- @logger.warn("resigning as master")
701
- @timers[:master].each do |timer|
740
+ # `:leader`, and `@is_leader`is set to `false`.
741
+ def resign_as_leader
742
+ if @is_leader
743
+ @logger.warn("resigning as leader")
744
+ @timers[:leader].each do |timer|
702
745
  timer.cancel
703
746
  end
704
- @timers[:master].clear
705
- @is_master = false
747
+ @timers[:leader].clear
748
+ @is_leader = false
706
749
  else
707
- @logger.debug("not currently master")
750
+ @logger.debug("not currently leader")
708
751
  end
709
752
  end
710
753
 
@@ -736,13 +779,13 @@ module Sensu
736
779
  end
737
780
 
738
781
  # Bootstrap the Sensu server process, setting up the keepalive
739
- # and check result consumers, and attemping to become the master
782
+ # and check result consumers, and attemping to become the leader
740
783
  # to carry out its duties. This method sets the process/daemon
741
784
  # `@state` to `:running`.
742
785
  def bootstrap
743
786
  setup_keepalives
744
787
  setup_results
745
- setup_master_monitor
788
+ setup_leader_monitor
746
789
  @state = :running
747
790
  end
748
791
 
@@ -759,7 +802,7 @@ module Sensu
759
802
  # set to `:pausing`, to indicate that it's in progress. All run
760
803
  # timers are cancelled, and the references are cleared. The
761
804
  # Sensu server will unsubscribe from all transport
762
- # subscriptions, resign as master (if currently the master),
805
+ # subscriptions, resign as leader (if currently the leader),
763
806
  # then set the process/daemon `@state` to `:paused`.
764
807
  def pause
765
808
  unless @state == :pausing || @state == :paused
@@ -769,7 +812,7 @@ module Sensu
769
812
  end
770
813
  @timers[:run].clear
771
814
  unsubscribe
772
- resign_as_master
815
+ resign_as_leader
773
816
  @state = :paused
774
817
  end
775
818
  end
data/sensu.gemspec CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.add_dependency "eventmachine", "1.0.3"
20
20
  s.add_dependency "sensu-em", "2.4.1"
21
21
  s.add_dependency "sensu-logger", "1.0.0"
22
- s.add_dependency "sensu-settings", "1.3.0"
22
+ s.add_dependency "sensu-settings", "1.7.0"
23
23
  s.add_dependency "sensu-extension", "1.1.2"
24
24
  s.add_dependency "sensu-extensions", "1.2.0"
25
25
  s.add_dependency "sensu-transport", "2.4.0"
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.17.2
4
+ version: 0.18.0.beta.1
5
5
  platform: java
6
6
  authors:
7
7
  - Sean Porter
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-04-08 00:00:00.000000000 Z
12
+ date: 2015-04-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: multi_json
@@ -87,12 +87,12 @@ dependencies:
87
87
  requirements:
88
88
  - - '='
89
89
  - !ruby/object:Gem::Version
90
- version: 1.3.0
90
+ version: 1.7.0
91
91
  requirement: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - '='
94
94
  - !ruby/object:Gem::Version
95
- version: 1.3.0
95
+ version: 1.7.0
96
96
  prerelease: false
97
97
  type: :runtime
98
98
  - !ruby/object:Gem::Dependency
@@ -283,9 +283,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
283
283
  version: '0'
284
284
  required_rubygems_version: !ruby/object:Gem::Requirement
285
285
  requirements:
286
- - - '>='
286
+ - - '>'
287
287
  - !ruby/object:Gem::Version
288
- version: '0'
288
+ version: 1.3.1
289
289
  requirements: []
290
290
  rubyforge_project:
291
291
  rubygems_version: 2.1.9