Close #801 - peak detector min datapoints (#1924)

Closes -- https://github.com/cantino/huginn/issues/801
Testing -- ran rspec
About --
  Adds an option `min_events` to the peak detector agent. The
  agent will start looking for peaks only after min number of
  events are accumulated.
This commit is contained in:
aeter 2017-03-11 02:05:10 +02:00 committed by Andrew Cantino
parent 845b04ee9d
commit d75e4c7cef
3 changed files with 39 additions and 5 deletions

View file

@ -12,6 +12,8 @@ module Agents
Set `expected_receive_period_in_days` to the maximum amount of time that you'd expect to pass between Events being received by this Agent.
You may set `window_duration_in_days` to change the default memory window length of `14` days, `min_peak_spacing_in_days` to change the default minimum peak spacing of `2` days (peaks closer together will be ignored), and `std_multiple` to change the default standard deviation threshold multiple of `3`.
You may set `min_events` for the minimal number of accumulated events before the agent starts detecting.
MD
event_description <<-MD
@ -26,8 +28,8 @@ module Agents
MD
def validate_options
unless options['expected_receive_period_in_days'].present? && options['message'].present? && options['value_path'].present?
errors.add(:base, "expected_receive_period_in_days, value_path, and message are required")
unless options['expected_receive_period_in_days'].present? && options['message'].present? && options['value_path'].present? && options['min_events'].present?
errors.add(:base, "expected_receive_period_in_days, value_path, min_events and message are required")
end
end
@ -36,7 +38,8 @@ module Agents
'expected_receive_period_in_days' => "2",
'group_by_path' => "filter",
'value_path' => "count",
'message' => "A peak of {{count}} was found in {{filter}}"
'message' => "A peak of {{count}} was found in {{filter}}",
'min_events' => '4',
}
end
@ -58,7 +61,9 @@ module Agents
memory['peaks'] ||= {}
memory['peaks'][group] ||= []
if memory['data'][group].length > 4 && (memory['peaks'][group].empty? || memory['peaks'][group].last < event.created_at.to_i - peak_spacing)
return if memory['data'][group].length <= options['min_events'].to_i
if memory['peaks'][group].empty? || memory['peaks'][group].last < event.created_at.to_i - peak_spacing
average_value, standard_deviation = stats_for(group, :skip_last => 1)
newest_value, newest_time = memory['data'][group][-1].map(&:to_f)

View file

@ -0,0 +1,19 @@
class AddMinEventsOptionToPeakDetectorAgents < ActiveRecord::Migration[5.0]
def up
Agents::PeakDetectorAgent.find_each do |agent|
if agent.options['min_events'].nil?
agent.options['min_events'] = '4'
agent.save(validate: false)
end
end
end
def down
Agents::PeakDetectorAgent.find_each do |agent|
if agent.options['min_events'].present?
agent.options.delete 'min_events'
agent.save(validate: false)
end
end
end
end

View file

@ -8,7 +8,8 @@ describe Agents::PeakDetectorAgent do
'expected_receive_period_in_days' => "2",
'group_by_path' => "filter",
'value_path' => "count",
'message' => "A peak was found"
'message' => "A peak was found",
'min_events' => "4",
}
}
@ -68,6 +69,15 @@ describe Agents::PeakDetectorAgent do
:pattern => { 'filter' => "something" })
expect(@agent.memory['peaks']['something'].length).to eq(2)
end
it 'waits and accumulates min events before triggering for peaks' do
@agent.options['min_peak_spacing_in_days'] = 1/24.0
@agent.options['min_events'] = '10'
@agent.receive build_events(:keys => ['count'],
:values => [1, 1, 1, 1, 1, 1, 10, 1, 1, 1, 1, 1, 1, 1, 10, 1].map {|i| [i]},
:pattern => { 'filter' => "something" })
expect(@agent.memory['peaks']['something'].length).to eq(1)
end
end
describe "validation" do