Skip to content

Commit 686e524

Browse files
chore(metrics): expose MetricsInterface as return type of single metric and further improve API docs (#3145)
Co-authored-by: Leandro Damascena <[email protected]>
1 parent c97d379 commit 686e524

File tree

10 files changed

+862
-310
lines changed

10 files changed

+862
-310
lines changed

Diff for: packages/metrics/README.md

+44-80
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
# Powertools for AWS Lambda (TypeScript) <!-- omit in toc -->
1+
# Powertools for AWS Lambda (TypeScript)
22

33
Powertools for AWS Lambda (TypeScript) is a developer toolkit to implement Serverless [best practices and increase developer velocity](https://docs.powertools.aws.dev/lambda/typescript/latest/#features).
44

55
You can use the library in both TypeScript and JavaScript code bases.
66

7-
- [Intro](#intro)
87
- [Usage](#usage)
9-
- [Basic usage](#basic-usage)
108
- [Flushing metrics](#flushing-metrics)
119
- [Capturing cold start as a metric](#capturing-cold-start-as-a-metric)
12-
- [Adding metadata](#adding-metadata)
10+
- [Class method decorator](#class-method-decorator)
11+
- [Middy.js middleware](#middyjs-middleware)
1312
- [Contribute](#contribute)
1413
- [Roadmap](#roadmap)
1514
- [Connect](#connect)
@@ -19,134 +18,99 @@ You can use the library in both TypeScript and JavaScript code bases.
1918
- [Using Lambda Layer](#using-lambda-layer)
2019
- [License](#license)
2120

22-
## Intro
23-
2421
## Usage
2522

23+
The library provides a utility function to emit metrics to CloudWatch using [Embedded Metric Format (EMF)](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format.html).
24+
2625
To get started, install the library by running:
2726

2827
```sh
2928
npm i @aws-lambda-powertools/metrics
3029
```
3130

32-
### Basic usage
31+
After initializing the Metrics class, you can add metrics using the [https://docs.powertools.aws.dev/lambda/typescript/latest/core/metrics/#creating-metrics](`addMetric()`) method. The metrics are stored in a buffer and are flushed when calling [https://docs.powertools.aws.dev/lambda/typescript/latest/core/metrics/#flushing-metrics](`publishStoredMetrics()`).
3332

34-
The library provides a utility function to emit metrics to CloudWatch using [Embedded Metric Format (EMF)](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format.html).
33+
Each metric can also have dimensions and metadata added to it.
3534

3635
```ts
37-
import { MetricUnit, Metrics } from '@aws-lambda-powertools/metrics';
36+
import { Metrics, MetricUnit } from '@aws-lambda-powertools/metrics';
3837

3938
const metrics = new Metrics({
4039
namespace: 'serverlessAirline',
4140
serviceName: 'orders',
41+
defaultDimensions: { environment: process.env.ENVIRONMENT },
4242
});
4343

44-
export const handler = async (
45-
_event: unknown,
46-
_context: unknown
47-
): Promise<void> => {
44+
export const handler = async (event: { requestId: string }) => {
45+
metrics.addMetadata('request_id', event.requestId);
4846
metrics.addMetric('successfulBooking', MetricUnit.Count, 1);
47+
metrics.publishStoredMetrics();
4948
};
5049
```
5150

5251
### Flushing metrics
5352

54-
As you finish adding all your metrics, you need to serialize and "flush them" by calling publishStoredMetrics(). This will print the metrics to standard output.
55-
56-
You can flush metrics automatically using one of the following methods:
53+
As you finish adding all your metrics, you need to serialize and "flush them" by calling `publishStoredMetrics()`, which will emit the metrics to stdout in the Embedded Metric Format (EMF). The metrics are then picked up by the Lambda runtime and sent to CloudWatch.
5754

58-
- manually by calling `publishStoredMetrics()` at the end of your Lambda function
55+
The `publishStoredMetrics()` method is synchronous and will block the event loop until the metrics are flushed. If you want Metrics to flush automatically at the end of your Lambda function, you can use the `@logMetrics()` decorator or the `logMetrics()` middleware.
5956

60-
```ts
61-
import { MetricUnit, Metrics } from '@aws-lambda-powertools/metrics';
62-
63-
const metrics = new Metrics({
64-
namespace: 'serverlessAirline',
65-
serviceName: 'orders',
66-
});
57+
### Capturing cold start as a metric
6758

68-
export const handler = async (
69-
_event: unknown,
70-
_context: unknown
71-
): Promise<void> => {
72-
metrics.addMetric('successfulBooking', MetricUnit.Count, 1);
73-
metrics.publishStoredMetrics();
74-
};
75-
```
59+
With Metrics, you can capture cold start as a metric by calling the `captureColdStartMetric()` method. This method will add a metric with the name `ColdStart` and the value `1` to the metrics buffer.
7660

77-
- middy compatible middleware `logMetrics()`
61+
This metric is flushed automatically as soon as the method is called, to ensure that the cold start is captured regardless of whether the metrics are flushed manually or automatically.
7862

7963
```ts
80-
import { MetricUnit, Metrics } from '@aws-lambda-powertools/metrics';
81-
import { logMetrics } from '@aws-lambda-powertools/metrics/middleware';
82-
import middy from '@middy/core';
64+
import { Metrics, MetricUnit } from '@aws-lambda-powertools/metrics';
8365

8466
const metrics = new Metrics({
8567
namespace: 'serverlessAirline',
8668
serviceName: 'orders',
8769
});
8870

89-
const lambdaHandler = async (
90-
_event: unknown,
91-
_context: unknown
92-
): Promise<void> => {
93-
metrics.addMetric('successfulBooking', MetricUnit.Count, 1);
71+
export const handler = async (event: { requestId: string }) => {
72+
metrics.captureColdStartMetric();
9473
};
95-
96-
export const handler = middy(lambdaHandler).use(logMetrics(metrics));
9774
```
9875

99-
- using decorator `@logMetrics()`
76+
Note that we don't emit a `ColdStart` metric with value `0` when the function is warm, as this would result in a high volume of metrics being emitted to CloudWatch, so you'll need to rely on the absence of the `ColdStart` metric to determine if the function is warm.
77+
78+
### Class method decorator
79+
80+
If you are using TypeScript and are comfortable with writing classes, you can use the `@logMetrics()` decorator to automatically flush metrics at the end of your Lambda function as well as configure additional options such as throwing an error if no metrics are added, capturing cold start as a metric, and more.
10081

10182
```ts
83+
import type { Context } from 'aws-lambda';
10284
import type { LambdaInterface } from '@aws-lambda-powertools/commons/types';
103-
import { MetricUnit, Metrics } from '@aws-lambda-powertools/metrics';
85+
import { Metrics, MetricUnit } from '@aws-lambda-powertools/metrics';
10486

10587
const metrics = new Metrics({
10688
namespace: 'serverlessAirline',
10789
serviceName: 'orders',
10890
});
10991

11092
class Lambda implements LambdaInterface {
111-
@metrics.logMetrics()
112-
public async handler(_event: unknown, _context: unknown): Promise<void> {
93+
⁣@metrics.logMetrics({ captureColdStartMetric: true, throwOnEmptyMetrics: true })
94+
public async handler(event: { requestId: string }, _: Context) {
95+
metrics.addMetadata('request_id', event.requestId);
11396
metrics.addMetric('successfulBooking', MetricUnit.Count, 1);
11497
}
11598
}
11699

117100
const handlerClass = new Lambda();
118-
export const handler = handlerClass.handler.bind(handlerClass);
101+
export const handler = handlerClass.handler.bind(handlerClass);
119102
```
120103

121-
Using the Middy middleware or decorator will automatically validate, serialize, and flush all your metrics.
122-
123-
### Capturing cold start as a metric
124-
125-
You can optionally capture cold start metrics with the logMetrics middleware or decorator via the captureColdStartMetric param.
126-
127-
```ts
128-
import type { LambdaInterface } from '@aws-lambda-powertools/commons/types';
129-
import { MetricUnit, Metrics } from '@aws-lambda-powertools/metrics';
130-
131-
const metrics = new Metrics({
132-
namespace: 'serverlessAirline',
133-
serviceName: 'orders',
134-
});
104+
Decorators are a Stage 3 proposal for JavaScript and are not yet part of the ECMAScript standard. The current implmementation in this library is based on the legacy TypeScript decorator syntax enabled by the [`experimentalDecorators` flag](https://www.typescriptlang.org/tsconfig/#experimentalDecorators) set to `true` in the `tsconfig.json` file.
135105

136-
export class MyFunction implements LambdaInterface {
137-
@metrics.logMetrics({ captureColdStartMetric: true })
138-
public async handler(_event: unknown, _context: unknown): Promise<void> {
139-
metrics.addMetric('successfulBooking', MetricUnit.Count, 1);
140-
}
141-
}
142-
```
106+
### Middy.js middleware
143107

144-
### Adding metadata
108+
If instead you are using [Middy.js](http://middy.js.org) and prefer to use middleware, you can use the `@logMetrics()` middleware to do the same as the class method decorator.
145109

146-
You can add high-cardinality data as part of your Metrics log with the `addMetadata` method. This is useful when you want to search highly contextual information along with your metrics in your logs.
110+
The `@logMetrics()` middleware can be used with Middy.js to automatically flush metrics at the end of your Lambda function as well as configure additional options such as throwing an error if no metrics are added, capturing cold start as a metric, and set default dimensions.
147111

148112
```ts
149-
import { MetricUnit, Metrics } from '@aws-lambda-powertools/metrics';
113+
import { Metrics, MetricUnit } from '@aws-lambda-powertools/metrics';
150114
import { logMetrics } from '@aws-lambda-powertools/metrics/middleware';
151115
import middy from '@middy/core';
152116

@@ -155,17 +119,17 @@ const metrics = new Metrics({
155119
serviceName: 'orders',
156120
});
157121

158-
const lambdaHandler = async (
159-
_event: unknown,
160-
_context: unknown
161-
): Promise<void> => {
122+
export const handler = middy(async (event) => {
123+
metrics.addMetadata('request_id', event.requestId);
162124
metrics.addMetric('successfulBooking', MetricUnit.Count, 1);
163-
metrics.addMetadata('bookingId', '7051cd10-6283-11ec-90d6-0242ac120003');
164-
};
165-
166-
export const handler = middy(lambdaHandler).use(logMetrics(metrics));
125+
}).use(logMetrics(metrics, {
126+
captureColdStartMetric: true,
127+
throwOnEmptyMetrics: true,
128+
}));
167129
```
168130

131+
The `logMetrics()` middleware is compatible with `@middy/[email protected]` and above.
132+
169133
## Contribute
170134

171135
If you are interested in contributing to this project, please refer to our [Contributing Guidelines](https://github.com/aws-powertools/powertools-lambda-typescript/blob/main/CONTRIBUTING.md).

0 commit comments

Comments
 (0)