def test_null_zero_sum(self): s = TimeSeries("s", 0, 1, 1, [None]) s.pathExpression = 's' [series] = functions.sumSeries({}, [s]) self.assertEqual(list(series), [None]) s = TimeSeries("s", 0, 1, 1, [None, 1]) s.pathExpression = 's' t = TimeSeries("s", 0, 1, 1, [None, None]) t.pathExpression = 't' [series] = functions.sumSeries({}, [s, t]) self.assertEqual(list(series), [None, 1])
def test_null_zero_sum(self): s = TimeSeries("s", 0, 1, 1, [None]) s.pathExpression = 's' [series] = functions.sumSeries({}, [s]) self.assertEqual(list(series), [None]) s = TimeSeries("s", 0, 1, 1, [None, 1]) s.pathExpression = 's' t = TimeSeries("s", 0, 1, 1, [None, None]) t.pathExpression = 't' [series] = functions.sumSeries({}, [s, t]) self.assertEqual(list(series), [None, 1])
def test_holt_winters(self): timespan = 3600 * 24 * 8 # 8 days stop = int(time.time()) step = 100 series = TimeSeries('foo.bar', stop - timespan, stop, step, [x**1.5 for x in range(0, timespan, step)]) series[10] = None series.pathExpression = 'foo.bar' self.write_series(series, [(100, timespan)]) ctx = { 'startTime': parseATTime('-1d'), } analysis = functions.holtWintersForecast(ctx, [series]) self.assertEqual(len(analysis), 1) analysis = functions.holtWintersConfidenceBands(ctx, [series]) self.assertEqual(len(analysis), 2) analysis = functions.holtWintersConfidenceArea(ctx, [series]) self.assertEqual(len(analysis), 2) analysis = functions.holtWintersAberration(ctx, [series]) self.assertEqual(len(analysis), 1)
def _generate_series_list(self): seriesList = [] config = [range(101), range(101), [1] + [None] * 100] for i, c in enumerate(config): name = "collectd.test-db{0}.load.value".format(i + 1) series = TimeSeries(name, 0, 101, 1, c) series.pathExpression = name seriesList.append(series) return seriesList
def _generate_series_list(self, config=(range(101), range(2, 103), [1] * 2 + [None] * 90 + [1] * 2 + [None] * 7)): seriesList = [] now = int(time.time()) for i, c in enumerate(config): name = "collectd.test-db{0}.load.value".format(i + 1) series = TimeSeries(name, now - 101, now, 1, c) series.pathExpression = name seriesList.append(series) return seriesList
def _generate_series_list(self, config=(range(101), range(2, 103), [1] * 2 + [None] * 90 + [1] * 2 + [None] * 7)): seriesList = [] now = int(time.time()) for i, c in enumerate(config): name = "collectd.test-db{0}.load.value".format(i + 1) series = TimeSeries(name, now - 101, now, 1, c) series.pathExpression = name seriesList.append(series) return seriesList
def test_time_stack(self): timespan = 3600 * 24 * 8 # 8 days stop = int(time.time()) step = 100 series = TimeSeries("foo.bar", stop - timespan, stop, step, [x ** 1.5 for x in range(0, timespan, step)]) series[10] = None series.pathExpression = "foo.bar" self.write_series(series, [(100, timespan)]) ctx = {"startTime": parseATTime("-1d"), "endTime": parseATTime("now")} stack = functions.timeStack(ctx, [series], "1d", 0, 7) self.assertEqual(len(stack), 7) stack = functions.timeStack(ctx, [series], "-1d", 0, 7) self.assertEqual(len(stack), 7)
def test_time_stack(self): timespan = 3600 * 24 * 8 # 8 days stop = int(time.time()) step = 100 series = TimeSeries('foo.bar', stop - timespan, stop, step, [x**1.5 for x in range(0, timespan, step)]) series[10] = None series.pathExpression = 'foo.bar' self.write_series(series, [(100, timespan)]) ctx = {'startTime': parseATTime('-1d'), 'endTime': parseATTime('now')} stack = functions.timeStack(ctx, [series], '1d', 0, 7) self.assertEqual(len(stack), 7) stack = functions.timeStack(ctx, [series], '-1d', 0, 7) self.assertEqual(len(stack), 7)
def mostChange(requestContext, seriesList): """ Takes one metric or a wildcard seriesList. For each series, determine the delta (last value minus first value) and create a new series with the delta as its only (first) value. Really only useful to create a bar graph showing metrics with the most change over a time period. """ results = [] for series in seriesList: newValues = [] delta = seriesdelta(series) newValues.append(delta) newName = "mostChange(%s)" % series.name newSeries = TimeSeries(newName, series.start, series.end, series.step, newValues) newSeries.pathExpression = newName results.append(newSeries) return results
def test_time_stack(self): timespan = 3600 * 24 * 8 # 8 days stop = int(time.time()) step = 100 series = TimeSeries('foo.bar', stop - timespan, stop, step, [x**1.5 for x in range(0, timespan, step)]) series[10] = None series.pathExpression = 'foo.bar' self.write_series(series, [(100, timespan)]) ctx = {'startTime': parseATTime('-1d'), 'endTime': parseATTime('now')} stack = functions.timeStack(ctx, [series], '1d', 0, 7) self.assertEqual(len(stack), 7) stack = functions.timeStack(ctx, [series], '-1d', 0, 7) self.assertEqual(len(stack), 7)
def test_holt_winters(self): timespan = 3600 * 24 * 8 # 8 days stop = int(time.time()) step = 100 series = TimeSeries('foo.bar', stop - timespan, stop, step, [x**1.5 for x in range(0, timespan, step)]) series[10] = None series.pathExpression = 'foo.bar' self.write_series(series, [(100, timespan)]) ctx = { 'startTime': parseATTime('-1d'), } analysis = functions.holtWintersForecast(ctx, [series]) self.assertEqual(len(analysis), 1) analysis = functions.holtWintersConfidenceBands(ctx, [series]) self.assertEqual(len(analysis), 2) analysis = functions.holtWintersConfidenceArea(ctx, [series]) self.assertEqual(len(analysis), 2) analysis = functions.holtWintersAberration(ctx, [series]) self.assertEqual(len(analysis), 1)
def ASAP(requestContext, seriesList, resolution=1000): ''' use the ASAP smoothing on a series https://arxiv.org/pdf/1703.00983.pdf https://raw.githubusercontent.com/stanford-futuredata/ASAP/master/ASAP.py :param requestContext: :param seriesList: :param resolution: either number of points to keep or a time resolution :return: smoothed(seriesList) ''' if not seriesList: return [] windowInterval = None if isinstance(resolution, six.string_types): delta = parseTimeOffset(resolution) windowInterval = to_seconds(delta) if windowInterval: previewSeconds = windowInterval else: previewSeconds = max([s.step for s in seriesList]) * int(resolution) # ignore original data and pull new, including our preview # data from earlier is needed to calculate the early results newContext = requestContext.copy() newContext['startTime'] = (requestContext['startTime'] - timedelta(seconds=previewSeconds)) previewList = evaluateTokens(newContext, requestContext['args'][0]) result = [] for series in previewList: if windowInterval: # the resolution here is really the number of points to maintain # so we need to convert the "seconds" to num points windowPoints = round((series.end - series.start) / windowInterval) else: use_res = int(resolution) if len(series) < use_res: use_res = len(series) windowPoints = use_res if isinstance(resolution, six.string_types): newName = 'asap(%s,"%s")' % (series.name, resolution) else: newName = "asap(%s,%s)" % (series.name, resolution) step_guess = (series.end - series.start) // windowPoints newSeries = TimeSeries(newName, series.start, series.end, step_guess, []) newSeries.pathExpression = newName # detect "none" lists if len([v for v in series if v is not None]) <= 1: newSeries.extend(series) else: # the "resolution" is a suggestion, # the algo will alter it some inorder # to get the best view for things new_s = smooth(series, windowPoints) # steps need to be ints, so we must force the issue new_step = round((series.end - series.start) / len(new_s)) newSeries.step = new_step newSeries.extend(new_s) result.append(newSeries) return result