1# Copyright 2015 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5"""Contains experimental alerting functions.""" 6 7from dashboard import find_change_points 8from dashboard.models import anomaly_config 9 10 11def RunFindChangePoints( 12 test, series, find_change_points_func=find_change_points.FindChangePoints, 13 **kwargs): 14 """Runs an change-point-finding function on part of a data series. 15 16 This function will be repeatedly called by SimulateAlertProcessingPipeline 17 in the bench_find_change_points module with the same Test entity but with more 18 and more points added to the end. 19 20 This is meant to imitate the current behavior of FindChangePoints on the perf 21 dashboard. 22 23 Args: 24 test: A graph_data.Test entity. 25 series: A list of ordered (x, y) pairs. 26 find_change_points_func: A function that has the same interface as 27 find_change_points.FindChangePoints. 28 **kwargs: Extra parameters to add to the anomaly config dict. 29 30 Returns: 31 A list of objects with the property x_value. 32 """ 33 # The anomaly threshold config dictionary determines how many points are 34 # analyzed and how far apart alerts should be, as well as other thresholds. 35 config = anomaly_config.GetAnomalyConfigDict(test) 36 config.update(kwargs) 37 38 # |series| contains all data so far in the Test, but typically when 39 # a test is processed (in find_anomalies.ProcessTest) only the last "window" 40 # of points is looked at. This window size depends on the test. To get the 41 # same behavior as the current default, we take only the last window. 42 series = _GetLastWindow(series, config.get('max_window_size')) 43 if len(series) < 2: 44 return [] 45 46 # Find anomalies for the requested test. 47 change_points = find_change_points_func(series, **config) 48 49 return _RemoveKnownAnomalies(test, change_points) 50 51 52def _GetLastWindow(series, window_size): 53 """Returns the last "window" of points in the data series.""" 54 if not window_size: 55 return series 56 return series[-window_size:] 57 58 59def _RemoveKnownAnomalies(test, change_points): 60 """Removes some anomalies and updates the given Test entity. 61 62 Args: 63 test: A Test entity, which has a property last_alerted_revision. 64 This property will be updated when this function is called. 65 change_points: A list of find_change_points.ChangePoint objects. It is 66 assumed that this list is sorted by the x_value property. 67 68 Returns: 69 A list of objects with the property x_value. 70 """ 71 # Avoid duplicates. 72 if test.last_alerted_revision: 73 change_points = [c for c in change_points 74 if c.x_value > test.last_alerted_revision] 75 76 if change_points: 77 # No need to call put(). The given Test entity will be re-used and we don't 78 # want to modify Test entity in the datastore. 79 test.last_alerted_revision = change_points[-1].x_value 80 81 return change_points 82 83 84def FindChangePointsWithAbsoluteChangeThreshold(test, series): 85 """Runs FindChangePoints, always setting an absolute change threshold.""" 86 return RunFindChangePoints( 87 test, series, 88 max_window_size=50, 89 multiple_of_std_dev=3.5, 90 min_relative_change=0.1, 91 min_absolute_change=1.0, 92 min_segment_size=6) 93