UNPKG

@aws-lambda-powertools/logger

Version:
569 lines 22.8 kB
import { Utility } from '@aws-lambda-powertools/commons'; import type { HandlerMethodDecorator } from '@aws-lambda-powertools/commons/types'; import type { Context } from 'aws-lambda'; import type { LogItem } from './formatter/LogItem.js'; import type { ConstructorOptions, InjectLambdaContextOptions, LogAttributes, LogItemExtraInput, LogItemMessage, LogLevel, LoggerInterface } from './types/Logger.js'; import type { LogKeys } from './types/logKeys.js'; /** * The Logger utility provides an opinionated logger with output structured as JSON for AWS Lambda. * * **Key features** * Capturing key fields from the Lambda context, cold starts, and structure logging output as JSON. * Logging Lambda invocation events when instructed (disabled by default). * Switch log level to `DEBUG` for a percentage of invocations (sampling). * Buffering logs for a specific request or invocation, and flushing them automatically on error or manually as needed. * Appending additional keys to structured logs at any point in time. * Providing a custom log formatter (Bring Your Own Formatter) to output logs in a structure compatible with your organization’s Logging RFC. * * After initializing the Logger class, you can use the methods to log messages at different levels. * * @example * ```typescript * import { Logger } from '@aws-lambda-powertools/logger'; * * const logger = new Logger({ serviceName: 'serverlessAirline' }); * * export const handler = async (event, context) => { * logger.info('This is an INFO log'); * logger.warn('This is a WARNING log'); * }; * ``` * * To enrich the log items with information from the Lambda context, you can use the {@link Logger.addContext | `addContext()`} method. * * @example * ```typescript * import { Logger } from '@aws-lambda-powertools/logger'; * * const logger = new Logger({ serviceName: 'serverlessAirline' }); * * export const handler = async (event, context) => { * logger.addContext(context); * * logger.info('This is an INFO log with some context'); * }; * ``` * * You can also add additional attributes to all log items using the {@link Logger.appendKeys | `appendKeys()`} method. * * @example * ```typescript * export const handler = async (event, context) => { * logger.appendKeys({ key1: 'value1' }); * * logger.info('This is an INFO log with additional keys'); * * logger.removeKeys(['key1']); * }; *``` * * If you write your functions as classes and use TypeScript, you can use the {@link Logger.injectLambdaContext | `injectLambdaContext()`} class method decorator * to automatically add context to your logs and clear the state after the invocation. * * If instead you use Middy.js middlewares, you use the {@link "middleware/middy".injectLambdaContext | `injectLambdaContext()`} middleware. * * @see https://docs.powertools.aws.dev/lambda/typescript/latest/core/logger/ */ declare class Logger extends Utility implements LoggerInterface { #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 console; /** * Custom config service instance used to configure the logger. */ private customConfigService?; /** * Environment variables service instance used to fetch environment variables. */ private envVarsService; /** * Whether to print the Lambda invocation event in the logs. */ private logEvent; /** * Formatter used to format the log items. * @default new PowertoolsLogFormatter() */ private logFormatter; /** * JSON indentation used to format the logs. */ private logIndentation; /** * Log level used internally by the current instance of Logger. */ private logLevel; /** * Persistent log attributes that will be logged in all log items. */ private persistentLogAttributes; /** * Standard attributes managed by Powertools that will be logged in all log items. */ private powertoolsLogData; /** * Temporary log attributes that can be appended with `appendKeys()` method. */ private temporaryLogAttributes; /** * Log level used by the current instance of Logger. * * Returns the log level as a number. The higher the number, the less verbose the logs. * To get the log level name, use the {@link getLevelName()} method. */ get level(): number; constructor(options?: ConstructorOptions); /** * Add the current Lambda function's invocation context data to the powertoolLogData property of the instance. * This context data will be part of all printed log items. * * @param context - The Lambda function's invocation context. */ addContext(context: Context): void; /** * @deprecated This method is deprecated and will be removed in the future major versions, please use {@link appendPersistentKeys() `appendPersistentKeys()`} instead. */ addPersistentLogAttributes(attributes: LogKeys): void; /** * Add the given temporary attributes (key-value pairs) to all log items generated by this Logger instance. * * If the key already exists in the attributes, it will be overwritten. If the key is one of `level`, `message`, `sampling_rate`, * `service`, or `timestamp` we will log a warning and drop the value. * * @param attributes - The attributes to add to all log items. */ appendKeys(attributes: LogKeys): void; /** * Add the given persistent attributes (key-value pairs) to all log items generated by this Logger instance. * * If the key already exists in the attributes, it will be overwritten. If the key is one of `level`, `message`, `sampling_rate`, * `service`, or `timestamp` we will log a warning and drop the value. * * @param attributes - The attributes to add to all log items. */ appendPersistentKeys(attributes: LogKeys): void; /** * Create a separate Logger instance, identical to the current one. * It's possible to overwrite the new instance options by passing them. * * @param options - The options to initialize the child logger with. */ createChild(options?: ConstructorOptions): Logger; /** * Print a log item with level CRITICAL. * * @param input - The log message. * @param extraInput - The extra input to log. */ critical(input: LogItemMessage, ...extraInput: LogItemExtraInput): void; /** * Print a log item with level DEBUG. * * @param input * @param extraInput - The extra input to log. */ debug(input: LogItemMessage, ...extraInput: LogItemExtraInput): void; /** * Print a log item with level ERROR. * * @param input - The log message. * @param extraInput - The extra input to log. */ error(input: LogItemMessage, ...extraInput: LogItemExtraInput): void; /** * Get the log level name of the current instance of Logger. * * Returns the log level name, i.e. `INFO`, `DEBUG`, etc. * To get the log level as a number, use the {@link Logger.level} property. */ getLevelName(): Uppercase<LogLevel>; /** * Return a boolean value. True means that the Lambda invocation events * are printed in the logs. */ getLogEvent(): boolean; /** * Return the persistent log attributes, which are the attributes * that will be logged in all log items. */ getPersistentLogAttributes(): LogAttributes; /** * Print a log item with level INFO. * * @param input - The log message. * @param extraInput - The extra input to log. */ info(input: LogItemMessage, ...extraInput: LogItemExtraInput): void; /** * Class method decorator that adds the current Lambda function context as extra * information in all log items. * * This decorator is useful when you want to enrich your logs with information * from the function context, such as the function name, version, and request ID, and more. * * @example * ```typescript * import { Logger } from '@aws-lambda-powertools/logger'; * import type { LambdaInterface } from '@aws-lambda-powertools/commons/types'; * * const logger = new Logger({ serviceName: 'serverlessAirline' }); * * class Lambda implements LambdaInterface { * // Decorate your handler class method * ⁣@logger.injectLambdaContext() * public async handler(_event: unknown, _context: unknown): Promise<void> { * logger.info('This is an INFO log with some context'); * } * } * * const handlerClass = new Lambda(); * export const handler = handlerClass.handler.bind(handlerClass); * ``` * * The decorator can also be used to log the Lambda invocation event; this can be configured both via * the `logEvent` parameter and the `POWERTOOLS_LOGGER_LOG_EVENT` environment variable. When both * are set, the `logEvent` parameter takes precedence. * * Additionally, the decorator can be used to reset the temporary keys added with the `appendKeys()` method * after the invocation, or to flush the buffer when an uncaught error is thrown in the handler. * * @see https://www.typescriptlang.org/docs/handbook/decorators.html#method-decorators * * @param options.logEvent - When `true` the logger will log the event. * @param options.resetKeys - When `true` the logger will clear temporary keys added with {@link Logger.appendKeys() `appendKeys()`} method. * @param options.flushBufferOnUncaughtError - When `true` the logger will flush the buffer when an uncaught error is thrown in the handler. */ injectLambdaContext(options?: InjectLambdaContextOptions): HandlerMethodDecorator; /** * @deprecated This method is deprecated and will be removed in the future major versions. Use {@link resetKeys()} instead. */ static injectLambdaContextAfterOrOnError(logger: Logger, _persistentAttributes: LogAttributes, options?: InjectLambdaContextOptions): void; /** * @deprecated - This method is deprecated and will be removed in the next major version. */ static injectLambdaContextBefore(logger: Logger, event: unknown, context: Context, options?: InjectLambdaContextOptions): void; /** * Log the AWS Lambda event payload for the current invocation if the environment variable `POWERTOOLS_LOGGER_LOG_EVENT` is set to `true`. * * @example * ```ts * process.env.POWERTOOLS_LOGGER_LOG_EVENT = 'true'; * * import { Logger } from '@aws-lambda-powertools/logger'; * * const logger = new Logger(); * * export const handler = async (event) => { * logger.logEventIfEnabled(event); * // ... your handler code * } * ``` * * @param event - The AWS Lambda event payload. * @param overwriteValue - Overwrite the environment variable value. */ logEventIfEnabled(event: unknown, overwriteValue?: boolean): void; /** * This method allows recalculating the initial sampling decision for changing * the log level to DEBUG based on a sample rate value used during initialization, * potentially yielding a different outcome. * * This only works for warm starts, because we don't to avoid double sampling. */ refreshSampleRateCalculation(): void; /** * Remove temporary attributes based on provided keys to all log items generated by this Logger instance. * * @param keys - The keys to remove. */ removeKeys(keys: string[]): void; /** * Remove the given keys from the persistent keys. * * @example * ```typescript * import { Logger } from '@aws-lambda-powertools/logger'; * * const logger = new Logger({ * persistentKeys: { * environment: 'prod', * }, * }); * * logger.removePersistentKeys(['environment']); * ``` * * @param keys - The keys to remove from the persistent attributes. */ removePersistentKeys(keys: string[]): void; /** * @deprecated This method is deprecated and will be removed in the future major versions. Use {@link removePersistentKeys()} instead. */ removePersistentLogAttributes(keys: string[]): void; /** * Remove all temporary log attributes added with {@link appendKeys() `appendKeys()`} method. */ resetKeys(): void; /** * Set the log level for this Logger instance. * * If the log level is set using AWS Lambda Advanced Logging Controls, it sets it * instead of the given log level to avoid data loss. * * @param logLevel The log level to set, i.e. `error`, `warn`, `info`, `debug`, etc. */ setLogLevel(logLevel: LogLevel): void; /** * @deprecated This method is deprecated and will be removed in the future major versions, please use {@link appendPersistentKeys() `appendPersistentKeys()`} instead. */ setPersistentLogAttributes(attributes: LogKeys): void; /** * Check whether the current Lambda invocation event should be printed in the logs or not. * * @param overwriteValue - Overwrite the environment variable value. */ shouldLogEvent(overwriteValue?: boolean): boolean; /** * Print a log item with level TRACE. * * @param input - The log message. * @param extraInput - The extra input to log. */ trace(input: LogItemMessage, ...extraInput: LogItemExtraInput): void; /** * Print a log item with level WARN. * * @param input - The log message. * @param extraInput - The extra input to log. */ warn(input: LogItemMessage, ...extraInput: LogItemExtraInput): void; /** * Factory method for instantiating logger instances. Used by `createChild` method. * Important for customization and subclassing. It allows subclasses, like `MyOwnLogger`, * to override its behavior while keeping the main business logic in `createChild` intact. * * @example * ```typescript * // MyOwnLogger subclass * class MyOwnLogger extends Logger { * protected createLogger(options?: ConstructorOptions): MyOwnLogger { * return new MyOwnLogger(options); * } * // No need to re-implement business logic from `createChild` and keep track on changes * public createChild(options?: ConstructorOptions): MyOwnLogger { * return super.createChild(options) as MyOwnLogger; * } * } * ``` * * @param options - Logger configuration options. */ protected createLogger(options?: ConstructorOptions): Logger; /** * A custom JSON replacer function that is used to serialize the log items. * * By default, we already extend the default serialization behavior to handle `BigInt` and `Error` objects, as well as remove circular references. * When a custom JSON replacer function is passed to the Logger constructor, it will be called **before** our custom rules for each key-value pair in the object being stringified. * * This allows you to customize the serialization while still benefiting from the default behavior. * * @see {@link ConstructorOptions.jsonReplacerFn} */ protected getJsonReplacer(): (key: string, value: unknown) => void; /** * Store information that is printed in all log items. * * @param attributes - The attributes to add to all log items. */ private addToPowertoolsLogData; private awsLogLevelShortCircuit; /** * Create a log item and populate it with the given log level, input, and extra input. */ protected createAndPopulateLogItem(logLevel: number, input: LogItemMessage, extraInput: LogItemExtraInput): LogItem; /** * Get the custom config service, an abstraction used to fetch environment variables. */ private getCustomConfigService; /** * Get the instance of a service that fetches environment variables. */ private getEnvVarsService; /** * Get the instance of a service that formats the structure of a * log item's keys and values in the desired way. */ private getLogFormatter; /** * Get the log level name from the log level number. * * For example, if the log level is 16, it will return 'WARN'. * * @param logLevel - The log level to get the name of */ private getLogLevelNameFromNumber; /** * Get information that will be added in all log item by * this Logger instance (different from user-provided persistent attributes). */ private getPowertoolsLogData; /** * Check if a given log level is valid. * * @param logLevel - The log level to check */ private isValidLogLevel; /** * Check if a given sample rate value is valid. * * @param sampleRateValue - The sample rate value to check */ private isValidSampleRate; /** * Print a given log with given log level. * * @param logLevel - The log level * @param log - The log item to print */ protected printLog(logLevel: number, log: LogItem): void; /** * Print or buffer a given log with given log level. * * @param logLevel - The log level threshold * @param input - The log message * @param extraInput - The extra input to log */ protected processLogItem(logLevel: number, input: LogItemMessage, extraInput: LogItemExtraInput): void; /** * 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 setConsole; /** * Set the Logger's customer config service instance, which will be used * to fetch environment variables. * * @param customConfigService - The custom config service */ private setCustomConfigService; /** * Set the initial Logger log level based on the following order: * 1. If a log level is set using AWS Lambda Advanced Logging Controls, it sets it. * 2. If a log level is passed to the constructor, it sets it. * 3. If a log level is set via custom config service, it sets it. * 4. If a log level is set via env variables, it sets it. * * If none of the above is true, the default log level applies (`INFO`). * * @param logLevel - Log level passed to the constructor */ private setInitialLogLevel; /** * Set the sample rate value with the following priority: * 1. Constructor value * 2. Custom config service value * 3. Environment variable value * 4. Default value (zero) * * @param sampleRateValue - The sample rate value */ private setInitialSampleRate; /** * If the log event feature is enabled via env variable, it sets a property that tracks whether * the event passed to the Lambda function handler should be logged or not. */ private setLogEvent; /** * Set the log formatter instance, in charge of giving a custom format * to the structured logs, and optionally the ordering for keys within logs. * * @param logFormatter - The log formatter * @param logRecordOrder - Optional list of keys to specify order in logs */ private setLogFormatter; /** * If the `POWERTOOLS_DEV` env variable is set, * add JSON indentation for pretty printing logs. */ private setLogIndentation; /** * Configure the Logger instance settings that will affect the Logger's behaviour * and the content of all logs. * * @param options - Options to configure the Logger instance */ private setOptions; /** * Add important data to the Logger instance that will affect the content of all logs. * * @param serviceName - The service name * @param environment - The environment * @param persistentKeys - The persistent log attributes */ private setPowertoolsLogData; /** * Add a log to the buffer. * * @param xrayTraceId - `_X_AMZN_TRACE_ID` of the request * @param log - Log to be buffered * @param logLevel - The level of log to be buffered */ protected bufferLogItem(xrayTraceId: string, log: LogItem, logLevel: number): void; /** * Flush all logs in the request buffer. * * This is called automatically when you use the {@link injectLambdaContext | `@logger.injectLambdaContext()`} decorator and * your function throws an error. */ flushBuffer(): void; /** * Empties the buffer for the current request */ clearBuffer(): void; /** * Test if the log meets the criteria to be buffered. * * @param traceId - `_X_AMZN_TRACE_ID` of the request * @param logLevel - The level of the log being considered */ protected shouldBufferLog(traceId: string | undefined, logLevel: number): boolean; /** * Set the correlation ID for the log item. * * This method can be used to set the correlation ID for the log item or to search for the correlation ID in the event. * * @example * ```typescript * import { Logger } from '@aws-lambda-powertools/logger'; * * const logger = new Logger(); * logger.setCorrelationId('my-correlation-id'); // sets the correlation ID directly with the first argument as value * ``` * * ```typescript * import { Logger } from '@aws-lambda-powertools/logger'; * import { search } from '@aws-lambda-powertools/logger/correlationId'; * * const logger = new Logger({ correlationIdSearchFn: search }); * logger.setCorrelationId(event, 'requestContext.requestId'); // sets the correlation ID from the event using JMSPath expression * ``` * * @param value - The value to set as the correlation ID or the event to search for the correlation ID * @param correlationIdPath - Optional JMESPath expression to extract the correlation ID for the payload */ setCorrelationId(value: unknown, correlationIdPath?: string): void; /** * Get the correlation ID from the log attributes. */ getCorrelationId(): unknown; } export { Logger }; //# sourceMappingURL=Logger.d.ts.map