lib/ustate/state.rb in ustate-client-0.0.3 vs lib/ustate/state.rb in ustate-client-0.0.4
- old
+ new
@@ -1,19 +1,156 @@
-class UState::State
- include Beefcake::Message
-
- optional :time, :int64, 1
- optional :state, :string, 2
- optional :service, :string, 3
- optional :host, :string, 4
- optional :description, :string, 5
- optional :once, :bool, 6
- optional :metric_f, :float, 15
+module UState
+ class State
+ include Beefcake::Message
+
+ optional :time, :int64, 1
+ optional :state, :string, 2
+ optional :service, :string, 3
+ optional :host, :string, 4
+ optional :description, :string, 5
+ optional :once, :bool, 6
+ optional :metric_f, :float, 15
- def metric
- @metric || metric_f
- end
+ # Average a set of states together. Chooses the mean metric, the mode
+ # state, mode service, and the mean time. If init is provided, its values
+ # override (where present) the computed ones.
+ def self.average(states, init = State.new)
+ init = case init
+ when State
+ init.dup
+ else
+ State.new init
+ end
+
+ # Metric
+ init.metric_f ||= states.inject(0.0) { |a, state|
+ a + (state.metric || 0)
+ } / states.size
+ if init.metric_f.nan?
+ init.metric_f = 0.0
+ end
- def metric=(m)
- @metric = m
+ # State
+ init.state ||= mode states.map(&:state)
+ init.service ||= mode states.map(&:service)
+
+ # Time
+ init.time ||= begin
+ (states.inject(0) do |a, state|
+ a + state.time.to_f
+ end / states.size).to_i
+ rescue
+ end
+ init.time ||= Time.now.to_i
+
+ init
+ end
+
+ # Sum a set of states together. Adds metrics, takes the mode state, mode
+ # service and the mean time. If init is provided, its values override
+ # (where present) the computed ones.
+ def self.sum(states, init = State.new)
+ init = case init
+ when State
+ init.dup
+ else
+ State.new init
+ end
+
+ # Metric
+ init.metric_f ||= states.inject(0.0) { |a, state|
+ a + (state.metric || 0)
+ }
+ if init.metric_f.nan?
+ init.metric_f = 0.0
+ end
+
+ # State
+ init.state ||= mode states.map(&:state)
+ init.service ||= mode states.map(&:service)
+
+ # Time
+ init.time ||= begin
+ (states.inject(0) do |a, state|
+ a + state.time.to_f
+ end / states.size).to_i
+ rescue
+ end
+ init.time ||= Time.now.to_i
+
+ init
+ end
+
+ # Finds the maximum of a set of states. Metric is the maximum. State is the
+ # highest, as defined by Dash.config.state_order. Time is the mean.
+ def self.max(states, init = State.new)
+ init = case init
+ when State
+ init.dup
+ else
+ State.new init
+ end
+
+ # Metric
+ init.metric_f ||= states.inject(0.0) { |a, state|
+ a + (state.metric || 0)
+ }
+ if init.metric_f.nan?
+ init.metric_f = 0.0
+ end
+
+ # State
+ init.state ||= states.inject(nil) do |max, state|
+ state.state if Dash.config[:state_order][state.state] > Dash.config[:state_order][max]
+ end
+
+ # Time
+ init.time ||= begin
+ (states.inject(0) { |a, state|
+ a + state.time.to_f
+ } / states.size).to_i
+ rescue
+ end
+ init.time ||= Time.now.to_i
+
+ init
+ end
+
+ def self.mode(array)
+ array.inject(Hash.new(0)) do |counts, e|
+ counts[e] += 1
+ counts
+ end.sort_by { |e, count| count }.last.first rescue nil
+ end
+
+ # Partition a list of states by a field
+ # Returns a hash of field_value => state
+ def self.partition(states, field)
+ states.inject(Hash.new { [] }) do |p, state|
+ p[state.send(field)] << state
+ end
+ end
+
+ # Sorts states by a field. nil values first.
+ def self.sort(states, field)
+ states.sort do |a, b|
+ a = a.send field
+ b = b.send field
+ if a.nil?
+ -1
+ elsif b.nil?
+ 1
+ else
+ a <=> b
+ end
+ end
+ end
+
+ def metric
+ @metric || metric_f
+ end
+
+ def metric=(m)
+ @metric = m
+ end
end
end