sensu 0.20.2 → 0.20.3

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: 540fbe4cb2a3911f73843e77d4986c9dd90b92d6
4
- data.tar.gz: eb5827d8b2d41073722166e1da5d6f3a6028be2c
3
+ metadata.gz: b4b99ec27fad9dd917c0a15b4aee2effdd105cce
4
+ data.tar.gz: 6599a21f33b14289af3b2d4bc7ecbf983853f16c
5
5
  SHA512:
6
- metadata.gz: 55b82945c73ea8689cc18ce34ba8c7cdb4c1ac9db752821afe012a7316af6fc5671850d79d94272f1d56ea9540cfcaf30f3073207aa47992ba6ddbcaeae93423
7
- data.tar.gz: f96fbe0650b5f7b533ed1a1325ca8de822f61218556e4023a12dff404a238dd8c2662cbe2f1266206f6416eb39407dcb210cfc410dabfb5499c9b29b6c9ae563
6
+ metadata.gz: 495461ab13fbeb0c93e838e66f357cb7a109fabd7467ec8fff47a78c565a1964563af35b580058a2f79bbaf0bff6c193939532744119c16a39fc83a72fc24620
7
+ data.tar.gz: 2d9b0a49eb9c887b9061020cf10ec42fe2c73e9e70d936def991a0f30243c8526536a8e4d069dafeaef7e31e0a3e304b3f283044a0fa892fb1bb1edc1c677882
data/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ## 0.20.3 - 2015-08-11
2
+
3
+ ### Other
4
+
5
+ Improved Sensu server leader election and resignation. Changes include the
6
+ use of a unique leader ID to help guard against cases where there could be
7
+ multiple leaders.
8
+
9
+ Fixed bridge extensions; they now receive all event data, including events
10
+ that normally do not result in an action (e.g. OK check results).
11
+
1
12
  ## 0.20.2 - 2015-08-06
2
13
 
3
14
  ### Other
@@ -1,7 +1,7 @@
1
1
  module Sensu
2
2
  unless defined?(Sensu::VERSION)
3
3
  # Sensu release version.
4
- VERSION = "0.20.2"
4
+ VERSION = "0.20.3"
5
5
 
6
6
  # Sensu check severities.
7
7
  SEVERITIES = %w[ok warning critical unknown]
@@ -126,37 +126,17 @@ module Sensu
126
126
  }.flatten.compact.uniq
127
127
  end
128
128
 
129
- # Run event bridge extensions, within the Sensu EventMachine
130
- # reactor (event loop). The extension API `safe_run()` method is
131
- # used to guard against most errors. Bridges are for relaying
132
- # Sensu event data to other services.
133
- #
134
- # @param event [Hash]
135
- def event_bridges(event)
136
- @extensions[:bridges].each do |name, bridge|
137
- bridge.safe_run(event) do |output, status|
138
- @logger.debug("bridge extension output", {
139
- :extension => bridge.definition,
140
- :output => output
141
- })
142
- end
143
- end
144
- end
145
-
146
129
  # Process an event: filter -> mutate -> handle.
147
130
  #
148
- # This method runs event bridges, relaying the event data to
149
- # other services. This method also determines the appropriate
150
- # handlers for the event, filtering and mutating the event data
151
- # for each of them. The `@handling_event_count` is incremented
152
- # by `1`, for each event handler chain (filter -> mutate ->
153
- # handle).
131
+ # This method determines the appropriate handlers for an event,
132
+ # filtering and mutating the event data for each of them. The
133
+ # `@handling_event_count` is incremented by `1`, for each event
134
+ # handler chain (filter -> mutate -> handle).
154
135
  #
155
136
  # @param event [Hash]
156
137
  def process_event(event)
157
138
  log_level = event[:check][:type] == "metric" ? :debug : :info
158
139
  @logger.send(log_level, "processing event", :event => event)
159
- event_bridges(event)
160
140
  handler_list = Array((event[:check][:handlers] || event[:check][:handler]) || "default")
161
141
  handlers = derive_handlers(handler_list)
162
142
  handlers.each do |handler|
@@ -169,6 +149,23 @@ module Sensu
169
149
  end
170
150
  end
171
151
 
152
+ # Run event bridge extensions, within the Sensu EventMachine
153
+ # reactor (event loop). The extension API `safe_run()` method is
154
+ # used to guard against most errors. Bridges are for relaying
155
+ # Sensu event data to other services.
156
+ #
157
+ # @param event [Hash]
158
+ def event_bridges(event)
159
+ @extensions[:bridges].each do |name, bridge|
160
+ bridge.safe_run(event) do |output, status|
161
+ @logger.debug("bridge extension output", {
162
+ :extension => bridge.definition,
163
+ :output => output
164
+ })
165
+ end
166
+ end
167
+ end
168
+
172
169
  # Add a check result to an aggregate. A check aggregate uses the
173
170
  # check `:name` and the `:issued` timestamp as its unique
174
171
  # identifier. An aggregate uses several counters: the total
@@ -300,8 +297,10 @@ module Sensu
300
297
  # registry. If the previous conditions are not met, and check
301
298
  # `:type` is `metric` and the `:status` is `0`, the event
302
299
  # registry is not updated, but the provided callback is called
303
- # with the event data. JSON serialization is used when storing
304
- # data in the registry.
300
+ # with the event data. All event data is sent to event bridge
301
+ # extensions, including events that do not normally produce an
302
+ # action. JSON serialization is used when storing data in the
303
+ # registry.
305
304
  #
306
305
  # @param client [Hash]
307
306
  # @param check [Hash]
@@ -338,6 +337,7 @@ module Sensu
338
337
  elsif check[:type] == "metric"
339
338
  callback.call(event)
340
339
  end
340
+ event_bridges(event)
341
341
  end
342
342
  end
343
343
 
@@ -746,8 +746,85 @@ module Sensu
746
746
  setup_check_result_aggregation_pruner
747
747
  end
748
748
 
749
+ # Create a lock timestamp (integer), current time including
750
+ # milliseconds. This method is used by Sensu server leader
751
+ # election.
752
+ #
753
+ # @return [Integer]
754
+ def create_lock_timestamp
755
+ (Time.now.to_f * 1000).to_i
756
+ end
757
+
758
+ # Create/return the unique Sensu server leader ID for the
759
+ # current process.
760
+ #
761
+ # @return [String]
762
+ def leader_id
763
+ @leader_id ||= random_uuid
764
+ end
765
+
766
+ # Become the Sensu server leader, responsible for specific
767
+ # duties (`leader_duties()`). Unless the current process is
768
+ # already the leader, this method sets the leader ID stored in
769
+ # Redis to the unique random leader ID for the process. If the
770
+ # leader ID in Redis is successfully updated, `@is_leader` is
771
+ # set to true and `leader_duties()` is called to begin the
772
+ # tasks/duties of the Sensu server leader.
773
+ def become_the_leader
774
+ unless @is_leader
775
+ @redis.set("leader", leader_id) do
776
+ @logger.info("i am now the leader")
777
+ @is_leader = true
778
+ leader_duties
779
+ end
780
+ else
781
+ @logger.debug("i am already the leader")
782
+ end
783
+ end
784
+
785
+ # Resign as leader, if the current process is the Sensu server
786
+ # leader. This method cancels and clears the leader timers,
787
+ # those with references stored in the timers hash under
788
+ # `:leader`, and `@is_leader` is set to `false`. The leader ID
789
+ # and leader lock are not removed from Redis, as they will be
790
+ # updated when another server is elected to be the leader, this
791
+ # method does not need to handle Redis connectivity issues.
792
+ def resign_as_leader
793
+ if @is_leader
794
+ @logger.warn("resigning as leader")
795
+ @timers[:leader].each do |timer|
796
+ timer.cancel
797
+ end
798
+ @timers[:leader].clear
799
+ @is_leader = false
800
+ else
801
+ @logger.debug("not currently the leader")
802
+ end
803
+ end
804
+
805
+ # Updates the Sensu server leader lock timestamp. The current
806
+ # leader ID is retrieved from Redis and compared with the leader
807
+ # ID of the current process to determine if it is still the
808
+ # Sensu server leader. If the current process is still the
809
+ # leader, the leader lock timestamp is updated. If the current
810
+ # process is no longer the leader (regicide),
811
+ # `resign_as_leader()` is called for cleanup, so there is not
812
+ # more than one leader.
813
+ def update_leader_lock
814
+ @redis.get("leader") do |current_leader_id|
815
+ if current_leader_id == leader_id
816
+ @redis.set("lock:leader", create_lock_timestamp) do
817
+ @logger.debug("updated leader lock timestamp")
818
+ end
819
+ else
820
+ @logger.warn("another sensu server has been elected as leader")
821
+ resign_as_leader
822
+ end
823
+ end
824
+ end
825
+
749
826
  # Request a leader election, a process to determine if the
750
- # current process is the leader Sensu server, with its
827
+ # current process is the Sensu server leader, with its
751
828
  # own/unique duties. A Redis key/value is used as a central
752
829
  # lock, using the "SETNX" Redis command to set the key/value if
753
830
  # it does not exist, using a timestamp for the value. If the
@@ -758,23 +835,18 @@ module Sensu
758
835
  # "GETSET" Redis command is used to set a new timestamp and
759
836
  # fetch the previous value to compare them, to determine if it
760
837
  # was set by the current process. If the current process is able
761
- # to set the timestamp value, it becomes the leader. The leader
762
- # has `@is_leader` set to `true`.
838
+ # to set the timestamp value, it becomes the leader.
763
839
  def request_leader_election
764
- @redis.setnx("lock:leader", Time.now.to_i) do |created|
840
+ @redis.setnx("lock:leader", create_lock_timestamp) do |created|
765
841
  if created
766
- @is_leader = true
767
- @logger.info("i am the leader")
768
- leader_duties
842
+ become_the_leader
769
843
  else
770
- @redis.get("lock:leader") do |current_timestamp|
771
- lock_timestamp = (Time.now.to_f * 1000).to_i
772
- if lock_timestamp - current_timestamp.to_i >= 30000
773
- @redis.getset("lock:leader", lock_timestamp) do |previous_timestamp|
774
- if previous_timestamp == current_timestamp
775
- @is_leader = true
776
- @logger.info("i am now the leader")
777
- leader_duties
844
+ @redis.get("lock:leader") do |current_lock_timestamp|
845
+ new_lock_timestamp = create_lock_timestamp
846
+ if new_lock_timestamp - current_lock_timestamp.to_i >= 30000
847
+ @redis.getset("lock:leader", new_lock_timestamp) do |previous_lock_timestamp|
848
+ if previous_lock_timestamp == current_lock_timestamp
849
+ become_the_leader
778
850
  end
779
851
  end
780
852
  end
@@ -795,33 +867,13 @@ module Sensu
795
867
  end
796
868
  @timers[:run] << EM::PeriodicTimer.new(10) do
797
869
  if @is_leader
798
- lock_timestamp = (Time.now.to_f * 1000).to_i
799
- @redis.set("lock:leader", lock_timestamp) do
800
- @logger.debug("updated leader lock timestamp")
801
- end
870
+ update_leader_lock
802
871
  else
803
872
  request_leader_election
804
873
  end
805
874
  end
806
875
  end
807
876
 
808
- # Resign as leader, if the current process is the Sensu server
809
- # leader. This method cancels and clears the leader timers,
810
- # those with references stored in the timers hash under
811
- # `:leader`, and `@is_leader`is set to `false`.
812
- def resign_as_leader
813
- if @is_leader
814
- @logger.warn("resigning as leader")
815
- @timers[:leader].each do |timer|
816
- timer.cancel
817
- end
818
- @timers[:leader].clear
819
- @is_leader = false
820
- else
821
- @logger.debug("not currently leader")
822
- end
823
- end
824
-
825
877
  # Unsubscribe from transport subscriptions (all of them). This
826
878
  # method is called when there are issues with connectivity, or
827
879
  # the process is stopping.
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.20.2
4
+ version: 0.20.3
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-08-06 00:00:00.000000000 Z
12
+ date: 2015-08-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: multi_json