From 24b12b919168bb6c1e1b6cb8c1e631c160bdfa33 Mon Sep 17 00:00:00 2001 From: Marcin Wielgus Date: Fri, 26 Feb 2016 13:44:16 +0100 Subject: [PATCH] In HPA metric client make average from samples from the last 1 minute --- .../podautoscaler/metrics/metrics_client.go | 29 +++++++++++--- .../metrics/metrics_client_test.go | 38 +++++++++++++++++++ 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/pkg/controller/podautoscaler/metrics/metrics_client.go b/pkg/controller/podautoscaler/metrics/metrics_client.go index 89e18ab91fd..9b41f8737ab 100644 --- a/pkg/controller/podautoscaler/metrics/metrics_client.go +++ b/pkg/controller/podautoscaler/metrics/metrics_client.go @@ -74,7 +74,7 @@ type HeapsterMetricsClient struct { } var averageFunction = func(metrics heapster.MetricResultList) (intAndFloat, int, time.Time) { - sum, count, timestamp := calculateSumFromLatestSample(metrics) + sum, count, timestamp := calculateSumFromTimeSample(metrics, time.Minute) result := intAndFloat{0, 0} if count > 0 { result.intValue = sum.intValue / int64(count) @@ -218,7 +218,7 @@ func (h *HeapsterMetricsClient) getForPods(metricSpec metricDefinition, namespac return &sum, timestamp, nil } -func calculateSumFromLatestSample(metrics heapster.MetricResultList) (sum intAndFloat, count int, timestamp time.Time) { +func calculateSumFromTimeSample(metrics heapster.MetricResultList, duration time.Duration) (sum intAndFloat, count int, timestamp time.Time) { sum = intAndFloat{0, 0} count = 0 timestamp = time.Time{} @@ -236,12 +236,29 @@ func calculateSumFromLatestSample(metrics heapster.MetricResultList) (sum intAnd if oldest == nil || newest.Timestamp.Before(*oldest) { oldest = &newest.Timestamp } + intervalSum := intAndFloat{0, 0} + intSumCount := 0 + floatSumCount := 0 + for _, metricPoint := range metrics.Metrics { + if metricPoint.Timestamp.Add(duration).After(newest.Timestamp) { + intervalSum.intValue += int64(metricPoint.Value) + intSumCount++ + if metricPoint.FloatValue != nil { + intervalSum.floatValue += *metricPoint.FloatValue + floatSumCount++ + } + } + } if newest.FloatValue == nil { - sum.intValue += int64(newest.Value) - sum.floatValue += float64(newest.Value) + if intSumCount > 0 { + sum.intValue += int64(intervalSum.intValue / int64(intSumCount)) + sum.floatValue += float64(intervalSum.intValue / int64(intSumCount)) + } } else { - sum.intValue += int64(*newest.FloatValue) - sum.floatValue += *newest.FloatValue + if floatSumCount > 0 { + sum.intValue += int64(intervalSum.floatValue / float64(floatSumCount)) + sum.floatValue += intervalSum.floatValue / float64(floatSumCount) + } } count++ } diff --git a/pkg/controller/podautoscaler/metrics/metrics_client_test.go b/pkg/controller/podautoscaler/metrics/metrics_client_test.go index 9af3cecfbd5..38dfaabaf9a 100644 --- a/pkg/controller/podautoscaler/metrics/metrics_client_test.go +++ b/pkg/controller/podautoscaler/metrics/metrics_client_test.go @@ -413,4 +413,42 @@ func TestCPUEmptyMetricsForOnePod(t *testing.T) { tc.runTest(t) } +func TestAggregateSum(t *testing.T) { + //calculateSumFromTimeSample(metrics heapster.MetricResultList, duration time.Duration) (sum intAndFloat, count int, timestamp time.Time) { + now := time.Now() + result := heapster.MetricResultList{ + Items: []heapster.MetricResult{ + { + Metrics: []heapster.MetricPoint{ + {now, 50, nil}, + {now.Add(-15 * time.Second), 100, nil}, + {now.Add(-60 * time.Second), 100000, nil}}, + LatestTimestamp: now, + }, + }, + } + sum, cnt, _ := calculateSumFromTimeSample(result, time.Minute) + assert.Equal(t, int64(75), sum.intValue) + assert.InEpsilon(t, 75.0, sum.floatValue, 0.1) + assert.Equal(t, 1, cnt) +} + +func TestAggregateSumSingle(t *testing.T) { + now := time.Now() + result := heapster.MetricResultList{ + Items: []heapster.MetricResult{ + { + Metrics: []heapster.MetricPoint{ + {now, 50, nil}, + {now.Add(-65 * time.Second), 100000, nil}}, + LatestTimestamp: now, + }, + }, + } + sum, cnt, _ := calculateSumFromTimeSample(result, time.Minute) + assert.Equal(t, int64(50), sum.intValue) + assert.InEpsilon(t, 50.0, sum.floatValue, 0.1) + assert.Equal(t, 1, cnt) +} + // TODO: add proper tests for request