sensu 0.18.0.beta → 0.18.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3562490d63bf32fe403bb3395f673b9be6ffd4e4
4
- data.tar.gz: ba043f59f239c29b9d8353d29ca892c6a3400384
3
+ metadata.gz: 5115ea5fab3b40df251fdcef28cb7108c84c4df4
4
+ data.tar.gz: a5094e790a5b5db1963da654bea369268d122f4e
5
5
  SHA512:
6
- metadata.gz: 0aae29a7af64355686413c1a4d6f108a1c59276312f31755065a5901faf5a5c508a9514b04e98e9942a651877b1d375a8ab9e3a6ba75e461310dded889c35b50
7
- data.tar.gz: d0cbbbd0000a734f411a4cdc5a396a40bb281cfcdbd77b009bc61365045de95eef0937a2ff169b25c76cea89b3371cb56a2779cfad31a817d04cccee0b2f57da
6
+ metadata.gz: ebbece50c019e3c927e52669be30c38e0be7ac1b91993bf72a4cc4d7ff19f19c161d0a55b6b4bb8ee27cff375405f0ba5c7ec7dcee84c26c97edc6584c929293
7
+ data.tar.gz: d0cb1a938d07ef543925234cc2c47eda1231d138e45500d1112c693f3373e1793e7d96aea078baf3c01a605f5347d09efd7a52fb6e713983c6ca2a1b246a0bf7
data/CHANGELOG.md CHANGED
@@ -13,6 +13,21 @@ Storing the latest check result for every client/check pair. This data is
13
13
  currently exposed via the API at `/clients/:client/history` and will be
14
14
  used by several upcoming features.
15
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
+
16
31
  ## 0.17.2 - 2015-04-08
17
32
 
18
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
 
@@ -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.18.0.beta"
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.4.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
 
@@ -481,8 +481,8 @@ module Sensu
481
481
 
482
482
  # Schedule check executions, using EventMachine periodic timers,
483
483
  # using a calculated execution splay. The timers are stored in
484
- # the timers hash under `:master`, as check request publishing
485
- # 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
486
486
  # cancelled etc. Check requests are not published if subdued.
487
487
  #
488
488
  # @param checks [Array] of definitions.
@@ -497,9 +497,9 @@ module Sensu
497
497
  end
498
498
  execution_splay = testing? ? 0 : calculate_check_execution_splay(check)
499
499
  interval = testing? ? 0.5 : check[:interval]
500
- @timers[:master] << EM::Timer.new(execution_splay) do
500
+ @timers[:leader] << EM::Timer.new(execution_splay) do
501
501
  create_check_request.call
502
- @timers[:master] << EM::PeriodicTimer.new(interval, &create_check_request)
502
+ @timers[:leader] << EM::PeriodicTimer.new(interval, &create_check_request)
503
503
  end
504
504
  end
505
505
  end
@@ -615,10 +615,10 @@ module Sensu
615
615
 
616
616
  # Set up the client monitor, a periodic timer to run
617
617
  # `determine_stale_clients()` every 30 seconds. The timer is
618
- # stored in the timers hash under `:master`.
618
+ # stored in the timers hash under `:leader`.
619
619
  def setup_client_monitor
620
620
  @logger.debug("monitoring client keepalives")
621
- @timers[:master] << EM::PeriodicTimer.new(30) do
621
+ @timers[:leader] << EM::PeriodicTimer.new(30) do
622
622
  determine_stale_clients
623
623
  end
624
624
  end
@@ -657,52 +657,53 @@ module Sensu
657
657
  # Set up the check result aggregation pruner, using periodic
658
658
  # timer to run `prune_check_result_aggregations()` every 20
659
659
  # seconds. The timer is stored in the timers hash under
660
- # `:master`.
660
+ # `:leader`.
661
661
  def setup_check_result_aggregation_pruner
662
662
  @logger.debug("pruning check result aggregations")
663
- @timers[:master] << EM::PeriodicTimer.new(20) do
663
+ @timers[:leader] << EM::PeriodicTimer.new(20) do
664
664
  prune_check_result_aggregations
665
665
  end
666
666
  end
667
667
 
668
- # Set up the master duties, tasks only performed by a single
668
+ # Set up the leader duties, tasks only performed by a single
669
669
  # Sensu server at a time. The duties include publishing check
670
670
  # requests, monitoring for stale clients, and pruning check
671
671
  # result aggregations.
672
- def master_duties
672
+ def leader_duties
673
673
  setup_check_request_publisher
674
674
  setup_client_monitor
675
675
  setup_check_result_aggregation_pruner
676
676
  end
677
677
 
678
- # Request a master election, a process to determine if the
679
- # 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
680
680
  # own/unique duties. A Redis key/value is used as a central
681
681
  # lock, using the "SETNX" Redis command to set the key/value if
682
682
  # it does not exist, using a timestamp for the value. If the
683
683
  # current process was able to create the key/value, it is the
684
- # 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
685
685
  # process was not able to create the key/value, but the current
686
686
  # timestamp value is equal to or over 30 seconds ago, the
687
687
  # "GETSET" Redis command is used to set a new timestamp and
688
688
  # fetch the previous value to compare them, to determine if it
689
689
  # was set by the current process. If the current process is able
690
- # to set the timestamp value, it becomes the master. The master
691
- # has `@is_master` set to `true`.
692
- def request_master_election
693
- @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|
694
694
  if created
695
- @is_master = true
696
- @logger.info("i am the master")
697
- master_duties
695
+ @is_leader = true
696
+ @logger.info("i am the leader")
697
+ leader_duties
698
698
  else
699
- @redis.get("lock:master") do |timestamp|
700
- if Time.now.to_i - timestamp.to_i >= 30
701
- @redis.getset("lock:master", Time.now.to_i) do |previous|
702
- if previous == timestamp
703
- @is_master = true
704
- @logger.info("i am now the master")
705
- 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
706
707
  end
707
708
  end
708
709
  end
@@ -711,41 +712,42 @@ module Sensu
711
712
  end
712
713
  end
713
714
 
714
- # Set up the master monitor. A one-time timer is used to run
715
- # `request_master_exection()` in 2 seconds. A periodic timer is
716
- # used to update the master lock timestamp if the current
717
- # 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(),
718
719
  # every 10 seconds. The timers are stored in the timers hash
719
720
  # under `:run`.
720
- def setup_master_monitor
721
+ def setup_leader_monitor
721
722
  @timers[:run] << EM::Timer.new(2) do
722
- request_master_election
723
+ request_leader_election
723
724
  end
724
725
  @timers[:run] << EM::PeriodicTimer.new(10) do
725
- if @is_master
726
- @redis.set("lock:master", Time.now.to_i) do
727
- @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")
728
730
  end
729
731
  else
730
- request_master_election
732
+ request_leader_election
731
733
  end
732
734
  end
733
735
  end
734
736
 
735
- # Resign as master, if the current process is the Sensu server
736
- # 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,
737
739
  # those with references stored in the timers hash under
738
- # `:master`, and `@is_master`is set to `false`.
739
- def resign_as_master
740
- if @is_master
741
- @logger.warn("resigning as master")
742
- @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|
743
745
  timer.cancel
744
746
  end
745
- @timers[:master].clear
746
- @is_master = false
747
+ @timers[:leader].clear
748
+ @is_leader = false
747
749
  else
748
- @logger.debug("not currently master")
750
+ @logger.debug("not currently leader")
749
751
  end
750
752
  end
751
753
 
@@ -777,13 +779,13 @@ module Sensu
777
779
  end
778
780
 
779
781
  # Bootstrap the Sensu server process, setting up the keepalive
780
- # and check result consumers, and attemping to become the master
782
+ # and check result consumers, and attemping to become the leader
781
783
  # to carry out its duties. This method sets the process/daemon
782
784
  # `@state` to `:running`.
783
785
  def bootstrap
784
786
  setup_keepalives
785
787
  setup_results
786
- setup_master_monitor
788
+ setup_leader_monitor
787
789
  @state = :running
788
790
  end
789
791
 
@@ -800,7 +802,7 @@ module Sensu
800
802
  # set to `:pausing`, to indicate that it's in progress. All run
801
803
  # timers are cancelled, and the references are cleared. The
802
804
  # Sensu server will unsubscribe from all transport
803
- # subscriptions, resign as master (if currently the master),
805
+ # subscriptions, resign as leader (if currently the leader),
804
806
  # then set the process/daemon `@state` to `:paused`.
805
807
  def pause
806
808
  unless @state == :pausing || @state == :paused
@@ -810,7 +812,7 @@ module Sensu
810
812
  end
811
813
  @timers[:run].clear
812
814
  unsubscribe
813
- resign_as_master
815
+ resign_as_leader
814
816
  @state = :paused
815
817
  end
816
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.4.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.18.0.beta
4
+ version: 0.18.0.beta.1
5
5
  platform: ruby
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-17 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,14 +87,14 @@ dependencies:
87
87
  requirements:
88
88
  - - '='
89
89
  - !ruby/object:Gem::Version
90
- version: 1.4.0
90
+ version: 1.7.0
91
91
  type: :runtime
92
92
  prerelease: false
93
93
  version_requirements: !ruby/object:Gem::Requirement
94
94
  requirements:
95
95
  - - '='
96
96
  - !ruby/object:Gem::Version
97
- version: 1.4.0
97
+ version: 1.7.0
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: sensu-extension
100
100
  requirement: !ruby/object:Gem::Requirement