@aws-lambda-powertools/metrics
Version:
The metrics package for the Powertools for AWS Lambda (TypeScript) library
625 lines • 25.6 kB
TypeScript
import { Utility } from '@aws-lambda-powertools/commons';
import type { HandlerMethodDecorator } from '@aws-lambda-powertools/commons/types';
import type { Dimensions, EmfOutput, ExtraOptions, MetricResolution, MetricsInterface, MetricsOptions, MetricUnit } from './types/index.js';
/**
* The Metrics utility creates custom metrics asynchronously by logging metrics to standard output following {@link https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format.html | Amazon CloudWatch Embedded Metric Format (EMF)}.
*
* These metrics can be visualized through Amazon CloudWatch Console.
*
* **Key features**
* * Aggregating up to 100 metrics using a single CloudWatch EMF object (large JSON blob).
* * Validating your metrics against common metric definitions mistakes (for example, metric unit, values, max dimensions, max metrics).
* * Metrics are created asynchronously by the CloudWatch service. You do not need any custom stacks, and there is no impact to Lambda function latency.
* * Creating a one-off metric with different dimensions.
*
* After initializing the Metrics class, you can add metrics using the {@link Metrics.addMetric | `addMetric()`} method.
* The metrics are stored in a buffer and are flushed when calling {@link Metrics.publishStoredMetrics | `publishStoredMetrics()`}.
* Each metric can have dimensions and metadata added to it.
*
* @example
* ```typescript
* import { Metrics, MetricUnit } from '@aws-lambda-powertools/metrics';
*
* const metrics = new Metrics({
* namespace: 'serverlessAirline',
* serviceName: 'orders',
* defaultDimensions: { environment: 'dev' },
* });
*
* export const handler = async (event: { requestId: string }) => {
* metrics.addMetadata('request_id', event.requestId);
* metrics.addMetric('successfulBooking', MetricUnit.Count, 1);
* metrics.publishStoredMetrics();
* };
* ```
*
* If you don't want to manually flush the metrics, you can use the {@link Metrics.logMetrics | `logMetrics()`} decorator or
* the Middy.js middleware to automatically flush the metrics after the handler function returns or throws an error.
*
* In addition to this, the decorator and middleware can also be configured to capture a `ColdStart` metric and
* set default dimensions for all metrics.
*
* **Class method decorator**
*
* @example
*
* ```typescript
* import type { Context } from 'aws-lambda';
* import type { LambdaInterface } from '@aws-lambda-powertools/commons/types';
* import { Metrics, MetricUnit } from '@aws-lambda-powertools/metrics';
*
* const metrics = new Metrics({
* namespace: 'serverlessAirline',
* serviceName: 'orders'
* });
*
* class Lambda implements LambdaInterface {
* @metrics.logMetrics({ captureColdStartMetric: true, throwOnEmptyMetrics: true })
* public async handler(_event: { requestId: string }, _: Context) {
* metrics.addMetadata('request_id', event.requestId);
* metrics.addMetric('successfulBooking', MetricUnit.Count, 1);
* }
* }
*
* const handlerClass = new Lambda();
* export const handler = handlerClass.handler.bind(handlerClass);
* ```
*
* Note that 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.
*
* **Middy.js middleware**
*
* @example
*
* ```typescript
* import { Metrics, MetricUnit } from '@aws-lambda-powertools/metrics';
* import { logMetrics } from '@aws-lambda-powertools/metrics/middleware';
* import middy from '@middy/core';
*
* const metrics = new Metrics({
* namespace: 'serverlessAirline',
* serviceName: 'orders'
* });
*
* export const handler = middy(async () => {
* metrics.addMetadata('request_id', event.requestId);
* metrics.addMetric('successfulBooking', MetricUnit.Count, 1);
* }).use(logMetrics(metrics, {
* captureColdStartMetric: true,
* throwOnEmptyMetrics: true,
* }));
* ```
*
* The `logMetrics()` middleware is compatible with `@middy/core@3.x` and above.
*
*/
declare class Metrics extends Utility implements MetricsInterface {
#private;
/**
* Console instance used to print logs.
*
* In AWS Lambda, we create a new instance of the Console class so that we can have
* full control over the output of the logs. In testing environments, we use the
* default console instance.
*
* This property is initialized in the constructor in setOptions().
*
* @private
*/
private console;
/**
* Custom configuration service for metrics
*/
private customConfigService?;
/**
* Default dimensions to be added to all metrics
* @default {}
*/
private defaultDimensions;
/**
* Additional dimensions for the current metrics context
* @default {}
*/
private dimensions;
/**
* Additional dimension sets for the current metrics context
* @default []
*/
private dimensionSets;
/**
* Name of the Lambda function
*/
private functionName?;
/**
* Flag indicating if this is a single metric instance
* @default false
*/
private isSingleMetric;
/**
* Additional metadata to be included with metrics
* @default {}
*/
private metadata;
/**
* Namespace for the metrics
*/
private namespace?;
/**
* Flag to determine if an error should be thrown when no metrics are recorded
* @default false
*/
private shouldThrowOnEmptyMetrics;
/**
* Storage for metrics before they are published
* @default {}
*/
private storedMetrics;
/**
* Whether to disable metrics
*/
private disabled;
constructor(options?: MetricsOptions);
/**
* Add a dimension to metrics.
*
* A dimension is a key-value pair that is used to group metrics, and it is included in all metrics emitted after it is added.
* Invalid dimension values are skipped and a warning is logged.
*
* When calling the {@link Metrics.publishStoredMetrics | `publishStoredMetrics()`} method, the dimensions are cleared. This type of
* dimension is useful when you want to add request-specific dimensions to your metrics. If you want to add dimensions that are
* included in all metrics, use the {@link Metrics.setDefaultDimensions | `setDefaultDimensions()`} method.
*
* @param name - The name of the dimension
* @param value - The value of the dimension
*/
addDimension(name: string, value: string): void;
/**
* Add multiple dimensions to the metrics.
*
* This method is useful when you want to add multiple dimensions to the metrics at once.
* Invalid dimension values are skipped and a warning is logged.
*
* When calling the {@link Metrics.publishStoredMetrics | `publishStoredMetrics()`} method, the dimensions are cleared. This type of
* dimension is useful when you want to add request-specific dimensions to your metrics. If you want to add dimensions that are
* included in all metrics, use the {@link Metrics.setDefaultDimensions | `setDefaultDimensions()`} method.
*
* @param dimensions - An object with key-value pairs of dimensions
*/
addDimensions(dimensions: Dimensions): void;
/**
* A metadata key-value pair to be included with metrics.
*
* You can use this method to add high-cardinality data as part of your metrics.
* This is useful when you want to search highly contextual information along with your metrics in your logs.
*
* Note that the metadata is not included in the Amazon CloudWatch UI, but it can be used to search and filter logs.
*
* @example
* ```typescript
* import { Metrics } from '@aws-lambda-powertools/metrics';
*
* const metrics = new Metrics({
* namespace: 'serverlessAirline',
* serviceName: 'orders'
* });
*
* export const handler = async (event) => {
* metrics.addMetadata('request_id', event.requestId);
* metrics.addMetric('successfulBooking', MetricUnit.Count, 1);
* metrics.publishStoredMetrics();
* };
* ```
*
* @param key - The key of the metadata
* @param value - The value of the metadata
*/
addMetadata(key: string, value: string): void;
/**
* Add a metric to the metrics buffer.
*
* By default, metrics are buffered and flushed when calling {@link Metrics.publishStoredMetrics | `publishStoredMetrics()`} method,
* or at the end of the handler function when using the {@link Metrics.logMetrics | `logMetrics()`} decorator or the Middy.js middleware.
*
* Metrics are emitted to standard output in the Amazon CloudWatch EMF (Embedded Metric Format) schema.
*
* You can add a metric by specifying the metric name, unit, and value. For convenience,
* we provide a set of constants for the most common units in the {@link MetricUnits | MetricUnit} dictionary object.
*
* Optionally, you can specify a {@link https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html#Resolution_definition | resolution}, which can be either `High` or `Standard`, using the {@link MetricResolutions | MetricResolution} dictionary object.
* By default, metrics are published with a resolution of `Standard`.
*
* @example
* ```typescript
* import { Metrics, MetricUnit } from '@aws-lambda-powertools/metrics';
*
* const metrics = new Metrics({
* namespace: 'serverlessAirline',
* serviceName: 'orders'
* });
*
* export const handler = async () => {
* metrics.addMetric('successfulBooking', MetricUnit.Count, 1);
* metrics.publishStoredMetrics();
* };
* ```
*
* @param name - The metric name
* @param unit - The metric unit, see {@link MetricUnits | MetricUnit}
* @param value - The metric value
* @param resolution - The metric resolution, see {@link MetricResolutions | MetricResolution}
*/
addMetric(name: string, unit: MetricUnit, value: number, resolution?: MetricResolution): void;
/**
* Immediately emit a `ColdStart` metric if this is a cold start invocation.
*
* A cold start is when AWS Lambda initializes a new instance of your function. To take advantage of this feature,
* you must instantiate the Metrics class outside of the handler function.
*
* By using this method, the metric will be emitted immediately without you having to call {@link Metrics.publishStoredMetrics | `publishStoredMetrics()`}.
*
* If you are using the {@link Metrics.logMetrics | `logMetrics()`} decorator, or the Middy.js middleware, you can enable this
* feature by setting the `captureColdStartMetric` option to `true`.
*
* @example
* ```typescript
* import { Metrics } from '@aws-lambda-powertools/metrics';
*
* const metrics = new Metrics({
* namespace: 'serverlessAirline',
* serviceName: 'orders'
* });
*
* export const handler = async () => {
* metrics.captureColdStartMetric();
* };
* ```
*
* @param functionName - Optional function name to use as `function_name` dimension in the metric. It's used only if the `functionName` constructor parameter or environment variable are not set.
*/
captureColdStartMetric(functionName?: string): void;
/**
* Clear all previously set default dimensions.
*
* This will remove all default dimensions set by the {@link Metrics.setDefaultDimensions | `setDefaultDimensions()`} method
* or via the `defaultDimensions` parameter in the constructor.
*
* @example
* ```typescript
* import { Metrics } from '@aws-lambda-powertools/metrics';
*
* const metrics = new Metrics({
* namespace: 'serverlessAirline',
* serviceName: 'orders',
* defaultDimensions: { environment: 'dev' },
* });
*
* metrics.setDefaultDimensions({ region: 'us-west-2' });
*
* // both environment and region dimensions are removed
* metrics.clearDefaultDimensions();
* ```
*/
clearDefaultDimensions(): void;
/**
* Clear all the dimensions added to the Metrics instance via {@link Metrics.addDimension | `addDimension()`} or {@link Metrics.addDimensions | `addDimensions()`}.
*
* These dimensions are normally cleared when calling {@link Metrics.publishStoredMetrics | `publishStoredMetrics()`}, but
* you can use this method to clear specific dimensions that you no longer need at runtime.
*
* This method does not clear the default dimensions set via {@link Metrics.setDefaultDimensions | `setDefaultDimensions()`} or via
* the `defaultDimensions` parameter in the constructor.
*
* @example
* ```typescript
* import { Metrics } from '@aws-lambda-powertools/metrics';
*
* const metrics = new Metrics({
* namespace: 'serverlessAirline',
* serviceName: 'orders'
* });
*
* export const handler = async () => {
* metrics.addDimension('region', 'us-west-2');
*
* // ...
*
* metrics.clearDimensions(); // olnly the region dimension is removed
* };
* ```
*
* The method is primarily intended for internal use, but it is exposed for advanced use cases.
*/
clearDimensions(): void;
/**
* Clear all the metadata added to the Metrics instance.
*
* Metadata is normally cleared when calling {@link Metrics.publishStoredMetrics | `publishStoredMetrics()`}, but
* you can use this method to clear specific metadata that you no longer need at runtime.
*
* The method is primarily intended for internal use, but it is exposed for advanced use cases.
*/
clearMetadata(): void;
/**
* Clear all the metrics stored in the buffer.
*
* This is useful when you want to clear the metrics stored in the buffer without publishing them.
*
* The method is primarily intended for internal use, but it is exposed for advanced use cases.
*/
clearMetrics(): void;
/**
* Check if there are stored metrics in the buffer.
*/
hasStoredMetrics(): boolean;
/**
* Whether metrics are disabled.
*/
protected isDisabled(): boolean;
/**
* A class method decorator to automatically log metrics after the method returns or throws an error.
*
* The decorator can be used with TypeScript classes and can be configured to optionally capture a `ColdStart` metric (see {@link Metrics.captureColdStartMetric | `captureColdStartMetric()`}),
* throw an error if no metrics are emitted (see {@link Metrics.setThrowOnEmptyMetrics | `setThrowOnEmptyMetrics()`}),
* and set default dimensions for all metrics (see {@link Metrics.setDefaultDimensions | `setDefaultDimensions()`}).
*
* @example
*
* ```typescript
* import type { Context } from 'aws-lambda';
* import type { LambdaInterface } from '@aws-lambda-powertools/commons/types';
* import { Metrics, MetricUnit } from '@aws-lambda-powertools/metrics';
*
* const metrics = new Metrics({
* namespace: 'serverlessAirline',
* serviceName: 'orders'
* });
*
* class Lambda implements LambdaInterface {
* @metrics.logMetrics({ captureColdStartMetric: true })
* public async handler(_event: { requestId: string }, _: Context) {
* metrics.addMetadata('request_id', event.requestId);
* metrics.addMetric('successfulBooking', MetricUnit.Count, 1);
* }
* }
*
* const handlerClass = new Lambda();
* export const handler = handlerClass.handler.bind(handlerClass);
* ```
*
* You can configure the decorator with the following options:
* - `captureColdStartMetric` - Whether to capture a `ColdStart` metric
* - `defaultDimensions` - Default dimensions to add to all metrics
* - `throwOnEmptyMetrics` - Whether to throw an error if no metrics are emitted
*
* @param options - Options to configure the behavior of the decorator, see {@link ExtraOptions}
*/
logMetrics(options?: ExtraOptions): HandlerMethodDecorator;
/**
* Flush the stored metrics to standard output.
*
* The method empties the metrics buffer and emits the metrics to standard output in the Amazon CloudWatch EMF (Embedded Metric Format) schema.
*
* When using the {@link Metrics.logMetrics | `logMetrics()`} decorator, or the Middy.js middleware, the metrics are automatically flushed after the handler function returns or throws an error.
*
* @example
* ```typescript
* import { Metrics, MetricUnit } from '@aws-lambda-powertools/metrics';
*
* const metrics = new Metrics({
* namespace: 'serverlessAirline',
* serviceName: 'orders'
* });
*
* export const handler = async () => {
* metrics.addMetric('successfulBooking', MetricUnit.Count, 1);
* metrics.publishStoredMetrics();
* };
* ```
*/
publishStoredMetrics(): void;
/**
* Sets the timestamp for the metric.
*
* If an integer is provided, it is assumed to be the epoch time in milliseconds.
* If a Date object is provided, it will be converted to epoch time in milliseconds.
*
* The timestamp must be a Date object or an integer representing an epoch time.
* This should not exceed 14 days in the past or be more than 2 hours in the future.
* Any metrics failing to meet this criteria will be skipped by Amazon CloudWatch.
*
* See: https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format_Specification.html
* See: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CloudWatch-Logs-Monitoring-CloudWatch-Metrics.html
*
* @example
* ```typescript
* import { MetricUnit, Metrics } from '@aws-lambda-powertools/metrics';
*
* const metrics = new Metrics({
* namespace: 'serverlessAirline',
* serviceName: 'orders',
* });
*
* export const handler = async () => {
* const metricTimestamp = new Date(Date.now() - 24 * 60 * 60 * 1000); // 24 hours ago
* metrics.setTimestamp(metricTimestamp);
* metrics.addMetric('successfulBooking', MetricUnit.Count, 1);
* };
* ```
* @param timestamp - The timestamp to set, which can be a number or a Date object.
*/
setTimestamp(timestamp: number | Date): void;
/**
* Serialize the stored metrics into a JSON object compliant with the Amazon CloudWatch EMF (Embedded Metric Format) schema.
*
* The EMF schema is a JSON object that contains the following properties:
* - `_aws`: An object containing the timestamp and the CloudWatch metrics.
* - `CloudWatchMetrics`: An array of CloudWatch metrics objects.
* - `Namespace`: The namespace of the metrics.
* - `Dimensions`: An array of dimensions for the metrics.
* - `Metrics`: An array of metric definitions.
*
* The object is then emitted to standard output, which in AWS Lambda is picked up by CloudWatch logs and processed asynchronously.
*/
serializeMetrics(): EmfOutput;
/**
* Set default dimensions that will be added to all metrics.
*
* This method will merge the provided dimensions with the existing default dimensions.
*
* @example
* ```typescript
* import { Metrics } from '@aws-lambda-powertools/metrics';
*
* const metrics = new Metrics({
* namespace: 'serverlessAirline',
* serviceName: 'orders',
* defaultDimensions: { environment: 'dev' },
* });
*
* // Default dimensions will contain both region and environment
* metrics.setDefaultDimensions({
* region: 'us-west-2',
* environment: 'prod',
* });
* ```
*
* @param dimensions - The dimensions to be added to the default dimensions object
*/
setDefaultDimensions(dimensions: Dimensions | undefined): void;
/**
* @deprecated Override the function name for `ColdStart` metrics inferred from the context either via:
* - `functionName` constructor parameter
* - `POWERTOOLS_FUNCTION_NAME` environment variable
* - {@link Metrics.captureColdStartMetric | `captureColdStartMetric('myFunctionName')`} method
*/
setFunctionName(name: string): void;
/**
* Set the flag to throw an error if no metrics are emitted.
*
* You can use this method to enable or disable this opt-in feature. This is useful if you want to ensure
* that at least one metric is emitted when flushing the metrics. This can be useful to catch bugs where
* metrics are not being emitted as expected.
*
* @param enabled - Whether to throw an error if no metrics are emitted
*/
setThrowOnEmptyMetrics(enabled: boolean): void;
/**
* Create a new Metrics instance configured to immediately flush a single metric.
*
* CloudWatch EMF uses the same dimensions and timestamp across all your metrics, this is useful when you have a metric that should have different dimensions
* or when you want to emit a single metric without buffering it.
*
* This method is used internally by the {@link Metrics.captureColdStartMetric | `captureColdStartMetric()`} method to emit the `ColdStart` metric immediately
* after the handler function is called.
*
* @example
* ```typescript
* import { Metrics } from '@aws-lambda-powertools/metrics';
*
* const metrics = new Metrics({
* namespace: 'serverlessAirline',
* serviceName: 'orders'
* });
*
* export const handler = async () => {
* const singleMetric = metrics.singleMetric();
* // The single metric will be emitted immediately
* singleMetric.addMetric('ColdStart', MetricUnit.Count, 1);
*
* // These other metrics will be buffered and emitted when calling `publishStoredMetrics()`
* metrics.addMetric('successfulBooking', MetricUnit.Count, 1);
* metrics.publishStoredMetrics();
* };
*/
singleMetric(): Metrics;
/**
* @deprecated Use {@link Metrics.setThrowOnEmptyMetrics | `setThrowOnEmptyMetrics()`} instead.
*/
throwOnEmptyMetrics(): void;
/**
* Gets the current number of dimensions count.
*/
private getCurrentDimensionsCount;
/**
* Get the custom config service if it exists.
*/
private getCustomConfigService;
/**
* Check if a metric is new or not.
*
* A metric is considered new if there is no metric with the same name already stored.
*
* When a metric is not new, we also check if the unit is consistent with the stored metric with
* the same name. If the units are inconsistent, we throw an error as this is likely a bug or typo.
* This can happen if a metric is added without using the `MetricUnit` helper in JavaScript codebases.
*
* @param name - The name of the metric
* @param unit - The unit of the metric
*/
private isNewMetric;
/**
* Initialize the console property as an instance of the internal version of `Console()` class (PR #748)
* or as the global node console if the `POWERTOOLS_DEV' env variable is set and has truthy value.
*
* @private
*/
private setConsole;
/**
* Set the custom config service to be used.
*
* @param customConfigService The custom config service to be used
*/
private setCustomConfigService;
/**
* Set the environment variables service to be used.
*/
private setEnvConfig;
/**
* Set the function name for the cold start metric.
*
* @param functionName - The function name to be used for the cold start metric set in the constructor
*/
protected setFunctionNameForColdStartMetric(functionName?: string): void;
/**
* Set the namespace to be used.
*
* @param namespace - The namespace to be used
*/
private setNamespace;
/**
* Set the disbaled flag based on the environment variables `POWERTOOLS_METRICS_DISABLED` and `POWERTOOLS_DEV`.
*
* The `POWERTOOLS_METRICS_DISABLED` environment variable takes precedence over `POWERTOOLS_DEV`.
*/
private setDisabled;
/**
* Set the options to be used by the Metrics instance.
*
* This method is used during the initialization of the Metrics instance.
*
* @param options - The options to be used
*/
private setOptions;
/**
* Set the service to be used.
*
* @param service - The service to be used
*/
private setService;
/**
* Store a metric in the buffer.
*
* If the buffer is full, or the metric reaches the maximum number of values,
* the metrics are flushed to stdout.
*
* @param name - The name of the metric to store
* @param unit - The unit of the metric to store
* @param value - The value of the metric to store
* @param resolution - The resolution of the metric to store
*/
private storeMetric;
}
export { Metrics };
//# sourceMappingURL=Metrics.d.ts.map