Class: PulseMeter::Sensor::Timeline Abstract
- Includes:
- Mixins::Utils
- Defined in:
- lib/pulse-meter/sensor/timeline.rb
Overview
Represents timelined sensor: series of values, one value for each consequent time interval.
Direct Known Subclasses
PulseMeter::Sensor::Timelined::Average, PulseMeter::Sensor::Timelined::Counter, PulseMeter::Sensor::Timelined::HashedCounter, PulseMeter::Sensor::Timelined::Max, PulseMeter::Sensor::Timelined::Min, PulseMeter::Sensor::Timelined::Percentile, PulseMeter::Sensor::Timelined::UniqCounter
Constant Summary collapse
- DEFAULTS =
Default values for some sensor parameters
{ :raw_data_ttl => 3600, :reduce_delay => 60, }
Constants included from Mixins::Dumper
Mixins::Dumper::DUMP_REDIS_KEY
Instance Attribute Summary collapse
-
#interval ⇒ Fixnum
readonly
Rotation interval.
-
#raw_data_ttl ⇒ Fixnum
readonly
How long unsummarized raw data will be stored before expiration.
-
#reduce_delay ⇒ Object
readonly
Returns the value of attribute reduce_delay.
-
#ttl ⇒ Fixnum
readonly
How long summarized data will be stored before expiration.
Attributes inherited from Base
Class Method Summary collapse
Instance Method Summary collapse
- #aggregate_event(key, value) ⇒ Object abstract
-
#cleanup ⇒ Object
Clean up all sensor metadata and data.
-
#current_interval_id ⇒ Fixnum
Returns current interval id.
-
#current_raw_data_key ⇒ Object
Returns Redis key by which raw data for current interval is stored.
-
#data_key(id) ⇒ Object
Returns Redis key by which summarized data for given interval is stored.
-
#event(value = nil) ⇒ Object
Processes event.
-
#get_interval_id(time) ⇒ Object
Returns interval id where given time is.
-
#get_timeline_value(interval_id) ⇒ SensorData
Returns sensor data for given interval.
-
#initialize(name, options) ⇒ Timeline
constructor
Initializes sensor with given name and parameters.
-
#raw_data_key(id) ⇒ Object
Returns Redis key by which raw data for given interval is stored.
-
#reduce(interval_id) ⇒ Object
Reduces data in given interval.
-
#reduce_all_raw ⇒ Object
Reduces data in all raw interval.
- #summarize(key) ⇒ Object abstract
-
#timeline(time_ago) ⇒ Array<SensorData>
Returts sensor data within some last seconds.
-
#timeline_within(from, till) ⇒ Array<SensorData>
Returts sensor data within given time.
Methods included from Mixins::Utils
#assert_positive_integer!, #assert_ranged_float!, #camelize, #camelize_keys, #constantize, #symbolize_keys, #titleize, #uniqid
Methods inherited from Base
Methods included from Mixins::Dumper
Constructor Details
#initialize(name, options) ⇒ Timeline
Initializes sensor with given name and parameters
32 33 34 35 36 37 38 |
# File 'lib/pulse-meter/sensor/timeline.rb', line 32 def initialize(name, ) @interval = assert_positive_integer!(, :interval) @ttl = assert_positive_integer!(, :ttl) @raw_data_ttl = assert_positive_integer!(, :raw_data_ttl, DEFAULTS[:raw_data_ttl]) @reduce_delay = assert_positive_integer!(, :reduce_delay, DEFAULTS[:reduce_delay]) super end |
Instance Attribute Details
#interval ⇒ Fixnum (readonly)
Returns Rotation interval.
18 19 20 |
# File 'lib/pulse-meter/sensor/timeline.rb', line 18 def interval @interval end |
#raw_data_ttl ⇒ Fixnum (readonly)
Returns How long unsummarized raw data will be stored before expiration.
18 |
# File 'lib/pulse-meter/sensor/timeline.rb', line 18 attr_reader :interval, :ttl, :raw_data_ttl, :reduce_delay |
#reduce_delay ⇒ Object (readonly)
Returns the value of attribute reduce_delay.
18 |
# File 'lib/pulse-meter/sensor/timeline.rb', line 18 attr_reader :interval, :ttl, :raw_data_ttl, :reduce_delay |
#ttl ⇒ Fixnum (readonly)
Returns How long summarized data will be stored before expiration.
18 |
# File 'lib/pulse-meter/sensor/timeline.rb', line 18 attr_reader :interval, :ttl, :raw_data_ttl, :reduce_delay |
Class Method Details
.reduce_all_raw ⇒ Object
88 89 90 91 92 |
# File 'lib/pulse-meter/sensor/timeline.rb', line 88 def self.reduce_all_raw list_objects.each do |sensor| sensor.reduce_all_raw if sensor.respond_to? :reduce_all_raw end end |
Instance Method Details
#aggregate_event(key, value) ⇒ Object
Registeres event for current interval identified by key
166 167 168 169 |
# File 'lib/pulse-meter/sensor/timeline.rb', line 166 def aggregate_event(key, value) # simple redis.set(key, value) end |
#cleanup ⇒ Object
Clean up all sensor metadata and data
41 42 43 44 45 46 47 |
# File 'lib/pulse-meter/sensor/timeline.rb', line 41 def cleanup keys = redis.keys(raw_data_key('*')) + redis.keys(data_key('*')) multi do keys.each{|key| redis.del(key)} end super end |
#current_interval_id ⇒ Fixnum
Returns current interval id
159 160 161 |
# File 'lib/pulse-meter/sensor/timeline.rb', line 159 def current_interval_id get_interval_id(Time.now) end |
#current_raw_data_key ⇒ Object
Returns Redis key by which raw data for current interval is stored
135 136 137 |
# File 'lib/pulse-meter/sensor/timeline.rb', line 135 def current_raw_data_key raw_data_key(current_interval_id) end |
#data_key(id) ⇒ Object
Returns Redis key by which summarized data for given interval is stored
147 148 149 |
# File 'lib/pulse-meter/sensor/timeline.rb', line 147 def data_key(id) "pulse_meter:data:#{name}:#{id}" end |
#event(value = nil) ⇒ Object
Processes event
50 51 52 53 54 55 56 |
# File 'lib/pulse-meter/sensor/timeline.rb', line 50 def event(value = nil) multi do current_key = current_raw_data_key aggregate_event(current_key, value) redis.expire(current_key, raw_data_ttl) end end |
#get_interval_id(time) ⇒ Object
Returns interval id where given time is
153 154 155 |
# File 'lib/pulse-meter/sensor/timeline.rb', line 153 def get_interval_id(time) (time.to_i / interval) * interval end |
#get_timeline_value(interval_id) ⇒ SensorData
Returns sensor data for given interval.
If the interval is not over yet makes its data in-memory summarization
and returns calculated value
126 127 128 129 130 131 132 |
# File 'lib/pulse-meter/sensor/timeline.rb', line 126 def get_timeline_value(interval_id) interval_data_key = data_key(interval_id) return SensorData.new(Time.at(interval_id), redis.get(interval_data_key)) if redis.exists(interval_data_key) interval_raw_data_key = raw_data_key(interval_id) return SensorData.new(Time.at(interval_id), summarize(interval_raw_data_key)) if redis.exists(interval_raw_data_key) SensorData.new(Time.at(interval_id), nil) end |
#raw_data_key(id) ⇒ Object
Returns Redis key by which raw data for given interval is stored
141 142 143 |
# File 'lib/pulse-meter/sensor/timeline.rb', line 141 def raw_data_key(id) "pulse_meter:raw:#{name}:#{id}" end |
#reduce(interval_id) ⇒ Object
Interval id is just unixtime of its lower bound. Ruduction is a process of ‘compressing’ all interval’s raw data to a single value. When reduction is done summarized data is saved to Redis separately with expiration time taken from sensor configuration.
Reduces data in given interval.
66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/pulse-meter/sensor/timeline.rb', line 66 def reduce(interval_id) interval_raw_data_key = raw_data_key(interval_id) return unless redis.exists(interval_raw_data_key) value = summarize(interval_raw_data_key) interval_data_key = data_key(interval_id) multi do redis.del(interval_raw_data_key) redis.set(interval_data_key, value) redis.expire(interval_data_key, ttl) end end |
#reduce_all_raw ⇒ Object
Reduces data in all raw interval
79 80 81 82 83 84 85 86 |
# File 'lib/pulse-meter/sensor/timeline.rb', line 79 def reduce_all_raw min_time = Time.now - reduce_delay - interval redis.keys(raw_data_key('*')).each do |key| interval_id = key.split(':').last next if Time.at(interval_id.to_i) > min_time reduce(interval_id) end end |
#summarize(key) ⇒ Object
Summarizes all event within interval to a single value
173 174 175 176 |
# File 'lib/pulse-meter/sensor/timeline.rb', line 173 def summarize(key) # simple redis.get(key) end |
#timeline(time_ago) ⇒ Array<SensorData>
Returts sensor data within some last seconds
98 99 100 101 102 |
# File 'lib/pulse-meter/sensor/timeline.rb', line 98 def timeline(time_ago) raise ArgumentError unless time_ago.respond_to?(:to_i) && time_ago.to_i > 0 now = Time.now timeline_within(now - time_ago.to_i, now) end |
#timeline_within(from, till) ⇒ Array<SensorData>
Returts sensor data within given time
109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/pulse-meter/sensor/timeline.rb', line 109 def timeline_within(from, till) raise ArgumentError unless from.kind_of?(Time) && till.kind_of?(Time) start_time, end_time = from.to_i, till.to_i current_interval_id = get_interval_id(start_time) + interval res = [] while current_interval_id < end_time res << get_timeline_value(current_interval_id) current_interval_id += interval end res end |