sensu 0.20.2 → 0.20.3
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 +11 -0
- data/lib/sensu/constants.rb +1 -1
- data/lib/sensu/server/process.rb +114 -62
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: b4b99ec27fad9dd917c0a15b4aee2effdd105cce
         | 
| 4 | 
            +
              data.tar.gz: 6599a21f33b14289af3b2d4bc7ecbf983853f16c
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 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
         | 
    
        data/lib/sensu/constants.rb
    CHANGED
    
    
    
        data/lib/sensu/server/process.rb
    CHANGED
    
    | @@ -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  | 
| 149 | 
            -
                  #  | 
| 150 | 
            -
                  #  | 
| 151 | 
            -
                  #  | 
| 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.  | 
| 304 | 
            -
                  #  | 
| 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  | 
| 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. | 
| 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",  | 
| 840 | 
            +
                    @redis.setnx("lock:leader", create_lock_timestamp) do |created|
         | 
| 765 841 | 
             
                      if created
         | 
| 766 | 
            -
                         | 
| 767 | 
            -
                        @logger.info("i am the leader")
         | 
| 768 | 
            -
                        leader_duties
         | 
| 842 | 
            +
                        become_the_leader
         | 
| 769 843 | 
             
                      else
         | 
| 770 | 
            -
                        @redis.get("lock:leader") do | | 
| 771 | 
            -
                           | 
| 772 | 
            -
                          if  | 
| 773 | 
            -
                            @redis.getset("lock:leader",  | 
| 774 | 
            -
                              if  | 
| 775 | 
            -
                                 | 
| 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 | 
            -
                         | 
| 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. | 
| 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- | 
| 12 | 
            +
            date: 2015-08-11 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: multi_json
         |