Skip to content

Commit 73609c1

Browse files
committed
add jsdoc on new functions
2 parents 2919e49 + 8d40471 commit 73609c1

File tree

2 files changed

+78
-5
lines changed

2 files changed

+78
-5
lines changed

Diff for: packages/metrics/src/Metrics.ts

+42-5
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class Metrics implements MetricsInterface {
8888
private isSingleMetric: boolean = false;
8989
private metadata: { [key: string]: string } = {};
9090
private namespace?: string;
91-
private raiseOnEmptyMetrics: boolean = false;
91+
private shouldRaiseOnEmptyMetrics: boolean = false;
9292
private storedMetrics: StoredMetrics = {};
9393

9494
public constructor(options: MetricsOptions = {}) {
@@ -165,6 +165,28 @@ class Metrics implements MetricsInterface {
165165
this.storedMetrics = {};
166166
}
167167

168+
169+
/**
170+
* Throw an Error if the metrics buffer is empty.
171+
*
172+
* @example
173+
*
174+
* ```typescript
175+
* import { Metrics, MetricUnits } from '@aws-lambda-powertools/metrics';
176+
* import { Context } from 'aws-lambda';
177+
*
178+
* const metrics = new Metrics({namespace:"ServerlessAirline", service:"orders"});
179+
*
180+
* export const handler = async (event: any, context: Context) => {
181+
* metrics.raiseOnEmptyMetrics();
182+
* metrics.purgeStoredMetrics(); // will throw since no metrics added.
183+
* }
184+
* ```
185+
*/
186+
public raiseOnEmptyMetrics(): void {
187+
this.shouldRaiseOnEmptyMetrics = true;
188+
}
189+
168190
/**
169191
* A decorator automating coldstart capture, raise on empty metrics and publishing metrics on handler exit.
170192
*
@@ -192,7 +214,9 @@ class Metrics implements MetricsInterface {
192214
*/
193215
public logMetrics(options: DecoratorOptions = {}): HandlerMethodDecorator {
194216
const { raiseOnEmptyMetrics, defaultDimensions, captureColdStartMetric } = options;
195-
this.raiseOnEmptyMetrics = raiseOnEmptyMetrics || false;
217+
if (raiseOnEmptyMetrics) {
218+
this.raiseOnEmptyMetrics();
219+
}
196220
if (defaultDimensions !== undefined) {
197221
this.setDefaultDimensions(defaultDimensions);
198222
}
@@ -202,7 +226,7 @@ class Metrics implements MetricsInterface {
202226
descriptor.value = (event, context, callback) => {
203227
this.functionName = context.functionName;
204228

205-
if (captureColdStartMetric) this.captureColdStart();
229+
if (captureColdStartMetric) this.captureColdStartMetric();
206230
try {
207231
const result = originalMethod?.apply(this, [event, context, callback]);
208232
return result;
@@ -245,7 +269,7 @@ class Metrics implements MetricsInterface {
245269
Name: metricDefinition.name,
246270
Unit: metricDefinition.unit,
247271
}));
248-
if (metricDefinitions.length === 0 && this.raiseOnEmptyMetrics) {
272+
if (metricDefinitions.length === 0 && this.shouldRaiseOnEmptyMetrics) {
249273
throw new RangeError('The number of metrics recorded must be higher than zero');
250274
}
251275

@@ -321,8 +345,21 @@ class Metrics implements MetricsInterface {
321345
* * Add function_name and service dimensions
322346
*
323347
* This has the advantage of keeping cold start metric separate from your application metrics, where you might have unrelated dimensions.
348+
*
349+
* @example
350+
*
351+
* ```typescript
352+
* import { Metrics, MetricUnits } from '@aws-lambda-powertools/metrics';
353+
* import { Context } from 'aws-lambda';
354+
*
355+
* const metrics = new Metrics({namespace:"ServerlessAirline", service:"orders"});
356+
*
357+
* export const handler = async (event: any, context: Context) => {
358+
* metrics.captureColdStartMetric();
359+
* }
360+
* ```
324361
*/
325-
public captureColdStart(): void {
362+
public captureColdStartMetric(): void {
326363
if (!this.isColdStart) return;
327364
this.isColdStart = false;
328365
const singleMetric = this.singleMetric();

Diff for: packages/metrics/tests/unit/Metrics.test.ts

+36
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,25 @@ describe('Class: Metrics', () => {
225225
});
226226

227227
describe('Feature: Cold Start', () => {
228+
test('Cold start metric should only be written out once and flushed automatically', async () => {
229+
const metrics = new Metrics({ namespace: 'test' });
230+
231+
const handler = async (event: any, context: Context) => {
232+
// Should generate only one log
233+
metrics.captureColdStartMetric();
234+
};
235+
236+
await handler(dummyEvent, dummyContext);
237+
await handler(dummyEvent, dummyContext);
238+
const loggedData = [JSON.parse(consoleSpy.mock.calls[0][0])];
239+
240+
expect(console.log).toBeCalledTimes(1);
241+
expect(loggedData[0]._aws.CloudWatchMetrics[0].Metrics.length).toBe(1);
242+
expect(loggedData[0]._aws.CloudWatchMetrics[0].Metrics[0].Name).toBe('ColdStart');
243+
expect(loggedData[0]._aws.CloudWatchMetrics[0].Metrics[0].Unit).toBe('Count');
244+
expect(loggedData[0].ColdStart).toBe(1);
245+
});
246+
228247
test('Cold start metric should only be written out once', async () => {
229248
const metrics = new Metrics({ namespace: 'test' });
230249

@@ -338,6 +357,23 @@ describe('Class: Metrics', () => {
338357
expect((<Error>e).message).toBe('The number of metrics recorded must be higher than zero');
339358
}
340359
});
360+
361+
test('Error should be thrown on empty metrics when raiseOnEmptyMetrics() is callse', async () => {
362+
expect.assertions(1);
363+
364+
const metrics = new Metrics({ namespace: 'test' });
365+
const handler = async (event: any, context: Context) => {
366+
metrics.raiseOnEmptyMetrics();
367+
// Logic goes here
368+
metrics.purgeStoredMetrics();
369+
};
370+
371+
try {
372+
await handler(dummyEvent, dummyContext);
373+
} catch (e) {
374+
expect((<Error>e).message).toBe('The number of metrics recorded must be higher than zero');
375+
}
376+
});
341377
});
342378

343379
describe('Feature: Auto log at limit', () => {

0 commit comments

Comments
 (0)