From 70ec7d86ca2f911c766321650d82856c2df4c113 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Wed, 21 Jun 2023 11:03:18 +0000 Subject: [PATCH 1/2] test: added failing test --- packages/metrics/tests/unit/Metrics.test.ts | 26 +++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/packages/metrics/tests/unit/Metrics.test.ts b/packages/metrics/tests/unit/Metrics.test.ts index b0f41073bf..e4addf34e4 100644 --- a/packages/metrics/tests/unit/Metrics.test.ts +++ b/packages/metrics/tests/unit/Metrics.test.ts @@ -701,6 +701,32 @@ describe('Class: Metrics', () => { ); }); + test('it should publish metrics when the array of values reaches the maximum size', () => { + // Prepare + const metrics: Metrics = new Metrics({ namespace: TEST_NAMESPACE }); + const consoleSpy = jest.spyOn(console, 'log'); + const metricName = 'test-metric'; + + // Act + for (let i = 0; i <= MAX_METRICS_SIZE; i++) { + metrics.addMetric(`${metricName}`, MetricUnits.Count, i); + } + metrics.publishStoredMetrics(); + + // Assess + // 2 calls to console.log: 1 for the first batch of metrics, 1 for the second batch (explicit call) + expect(consoleSpy).toHaveBeenCalledTimes(2); + const firstMetricsJson = JSON.parse( + consoleSpy.mock.calls[0][0] + ) as EmfOutput; + const secondMetricsJson = JSON.parse( + consoleSpy.mock.calls[1][0] + ) as EmfOutput; + + expect(firstMetricsJson[metricName]).toHaveLength(MAX_METRICS_SIZE); + expect(secondMetricsJson[metricName]).toHaveLength(1); + }); + test('it should not publish metrics if stored metrics count has not reached max metric size threshold', () => { // Prepare const metrics: Metrics = new Metrics({ namespace: TEST_NAMESPACE }); From bd31e321008cc609a2f46a20284f9a1707f62538 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Thu, 22 Jun 2023 20:55:02 +0000 Subject: [PATCH 2/2] fix(metrics): flush metrics when values array reaches max size --- packages/metrics/src/Metrics.ts | 9 ++++++++- packages/metrics/src/constants.ts | 17 +++++++++++++---- packages/metrics/tests/unit/Metrics.test.ts | 9 ++++++--- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/packages/metrics/src/Metrics.ts b/packages/metrics/src/Metrics.ts index 168fa255c3..0a236db877 100644 --- a/packages/metrics/src/Metrics.ts +++ b/packages/metrics/src/Metrics.ts @@ -7,6 +7,7 @@ import { MAX_METRICS_SIZE, DEFAULT_NAMESPACE, COLD_START_METRIC, + MAX_METRIC_VALUES_SIZE, } from './constants'; import { MetricsOptions, @@ -662,7 +663,10 @@ class Metrics extends Utility implements MetricsInterface { } /** - * Stores a metric in the buffer + * Stores a metric in the buffer. + * + * If the buffer is full, or the metric reaches the maximum number of values, + * the buffer is published to stdout. * * @param name The name of the metric to store * @param unit The unit of the metric to store @@ -692,6 +696,9 @@ class Metrics extends Utility implements MetricsInterface { storedMetric.value = [storedMetric.value]; } storedMetric.value.push(value); + if (storedMetric.value.length === MAX_METRIC_VALUES_SIZE) { + this.publishStoredMetrics(); + } } } } diff --git a/packages/metrics/src/constants.ts b/packages/metrics/src/constants.ts index 0dcf9ff255..5cdbf6a955 100644 --- a/packages/metrics/src/constants.ts +++ b/packages/metrics/src/constants.ts @@ -1,4 +1,13 @@ -export const COLD_START_METRIC = 'ColdStart'; -export const DEFAULT_NAMESPACE = 'default_namespace'; -export const MAX_METRICS_SIZE = 100; -export const MAX_DIMENSION_COUNT = 29; +const COLD_START_METRIC = 'ColdStart'; +const DEFAULT_NAMESPACE = 'default_namespace'; +const MAX_METRICS_SIZE = 100; +const MAX_METRIC_VALUES_SIZE = 100; +const MAX_DIMENSION_COUNT = 29; + +export { + COLD_START_METRIC, + DEFAULT_NAMESPACE, + MAX_METRICS_SIZE, + MAX_METRIC_VALUES_SIZE, + MAX_DIMENSION_COUNT, +}; diff --git a/packages/metrics/tests/unit/Metrics.test.ts b/packages/metrics/tests/unit/Metrics.test.ts index e4addf34e4..42c5f2ded8 100644 --- a/packages/metrics/tests/unit/Metrics.test.ts +++ b/packages/metrics/tests/unit/Metrics.test.ts @@ -16,6 +16,7 @@ import { DEFAULT_NAMESPACE, MAX_DIMENSION_COUNT, MAX_METRICS_SIZE, + MAX_METRIC_VALUES_SIZE, } from '../../src/constants'; import { setupDecoratorLambdaHandler } from '../helpers/metricsUtils'; import { @@ -708,7 +709,7 @@ describe('Class: Metrics', () => { const metricName = 'test-metric'; // Act - for (let i = 0; i <= MAX_METRICS_SIZE; i++) { + for (let i = 0; i <= MAX_METRIC_VALUES_SIZE; i++) { metrics.addMetric(`${metricName}`, MetricUnits.Count, i); } metrics.publishStoredMetrics(); @@ -723,8 +724,10 @@ describe('Class: Metrics', () => { consoleSpy.mock.calls[1][0] ) as EmfOutput; - expect(firstMetricsJson[metricName]).toHaveLength(MAX_METRICS_SIZE); - expect(secondMetricsJson[metricName]).toHaveLength(1); + // The first batch of values should be an array of size MAX_METRIC_VALUES_SIZE + expect(firstMetricsJson[metricName]).toHaveLength(MAX_METRIC_VALUES_SIZE); + // The second should be a single value (the last value added, which is 100 given we start from 0) + expect(secondMetricsJson[metricName]).toEqual(100); }); test('it should not publish metrics if stored metrics count has not reached max metric size threshold', () => {