1
1
import type { EnvironmentVariablesService } from '../config/EnvironmentVariablesService.js' ;
2
- import type {
3
- LogAttributes ,
4
- LogFormatterInterface ,
5
- LogFormatterOptions ,
6
- } from '../types/Log.js' ;
7
- import type { UnformattedAttributes } from '../types/Logger.js' ;
2
+ import type { LogAttributes } from '../types/Logger.js' ;
3
+ import type { LogFormatterOptions } from '../types/formatters.js' ;
4
+ import type { UnformattedAttributes } from '../types/logKeys.js' ;
8
5
import type { LogItem } from './LogItem.js' ;
9
6
10
7
/**
11
- * This class defines and implements common methods for the formatting of log attributes.
8
+ * Class that defines and implements common methods for the formatting of log attributes.
12
9
*
13
- * @class
10
+ * When creating a custom log formatter, you should extend this class and implement the
11
+ * {@link formatAttributes | formatAttributes()} method to define the structure of the log item.
12
+ *
13
+ * @abstract
14
14
*/
15
- abstract class LogFormatter implements LogFormatterInterface {
15
+ abstract class LogFormatter {
16
16
/**
17
- * EnvironmentVariablesService instance.
18
- * If set, it allows to access environment variables.
17
+ * Instance of the {@link EnvironmentVariablesService} to use for configuration.
19
18
*/
20
19
protected envVarsService ?: EnvironmentVariablesService ;
21
20
@@ -24,21 +23,85 @@ abstract class LogFormatter implements LogFormatterInterface {
24
23
}
25
24
26
25
/**
27
- * It formats key-value pairs of log attributes.
26
+ * Format key-value pairs of log attributes.
27
+ *
28
+ * You should implement this method in a subclass to define the structure of the log item.
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * import { LogFormatter, LogItem } from '@aws-lambda-powertools/logger';
33
+ * import type {
34
+ * LogAttributes,
35
+ * UnformattedAttributes,
36
+ * } from '@aws-lambda-powertools/logger/types';
37
+ *
38
+ * class MyCompanyLogFormatter extends LogFormatter {
39
+ * public formatAttributes(
40
+ * attributes: UnformattedAttributes,
41
+ * additionalLogAttributes: LogAttributes
42
+ * ): LogItem {
43
+ * const baseAttributes: MyCompanyLog = {
44
+ * message: attributes.message,
45
+ * service: attributes.serviceName,
46
+ * environment: attributes.environment,
47
+ * awsRegion: attributes.awsRegion,
48
+ * correlationIds: {
49
+ * awsRequestId: attributes.lambdaContext?.awsRequestId,
50
+ * xRayTraceId: attributes.xRayTraceId,
51
+ * },
52
+ * lambdaFunction: {
53
+ * name: attributes.lambdaContext?.functionName,
54
+ * arn: attributes.lambdaContext?.invokedFunctionArn,
55
+ * memoryLimitInMB: attributes.lambdaContext?.memoryLimitInMB,
56
+ * version: attributes.lambdaContext?.functionVersion,
57
+ * coldStart: attributes.lambdaContext?.coldStart,
58
+ * },
59
+ * logLevel: attributes.logLevel,
60
+ * timestamp: this.formatTimestamp(attributes.timestamp), // You can extend this function
61
+ * logger: {
62
+ * sampleRateValue: attributes.sampleRateValue,
63
+ * },
64
+ * };
65
+ *
66
+ * const logItem = new LogItem({ attributes: baseAttributes });
67
+ * // add any attributes not explicitly defined
68
+ * logItem.addAttributes(additionalLogAttributes);
69
+ *
70
+ * return logItem;
71
+ * }
72
+ * }
28
73
*
29
- * @param {UnformattedAttributes } attributes - unformatted attributes
30
- * @param {LogAttributes } additionalLogAttributes - additional log attributes
74
+ * export { MyCompanyLogFormatter };
75
+ * ```
76
+ *
77
+ * @param attributes - Unformatted attributes
78
+ * @param additionalLogAttributes - Additional log attributes
31
79
*/
32
80
public abstract formatAttributes (
33
81
attributes : UnformattedAttributes ,
34
82
additionalLogAttributes : LogAttributes
35
83
) : LogItem ;
36
84
37
85
/**
38
- * Format a given Error parameter.
86
+ * Format an error into a loggable object.
87
+ *
88
+ * @example
89
+ * ```json
90
+ * {
91
+ * "name": "Error",
92
+ * "location": "file.js:1",
93
+ * "message": "An error occurred",
94
+ * "stack": "Error: An error occurred\n at file.js:1\n at file.js:2\n at file.js:3",
95
+ * "cause": {
96
+ * "name": "OtherError",
97
+ * "location": "file.js:2",
98
+ * "message": "Another error occurred",
99
+ * "stack": "Error: Another error occurred\n at file.js:2\n at file.js:3\n at file.js:4"
100
+ * }
101
+ * }
102
+ * ```
39
103
*
40
- * @param {Error } error - error to format
41
- * @returns {LogAttributes } formatted error
104
+ * @param error - Error to format
42
105
*/
43
106
public formatError ( error : Error ) : LogAttributes {
44
107
return {
@@ -54,11 +117,14 @@ abstract class LogFormatter implements LogFormatterInterface {
54
117
}
55
118
56
119
/**
57
- * Format a given date into an ISO 8601 string, considering the configured timezone.
58
- * If `envVarsService` is set and the configured timezone differs from 'UTC',
59
- * the date is formatted to that timezone. Otherwise, it defaults to 'UTC'.
120
+ * Format a date into an ISO 8601 string with the configured timezone.
121
+ *
122
+ * If the log formatter is passed an {@link EnvironmentVariablesService} instance
123
+ * during construction, the timezone is read from the `TZ` environment variable, if present.
60
124
*
61
- * @param {Date } now - The date to format
125
+ * Otherwise, the timezone defaults to ':UTC'.
126
+ *
127
+ * @param now - The date to format
62
128
*/
63
129
public formatTimestamp ( now : Date ) : string {
64
130
const defaultTimezone = 'UTC' ;
@@ -75,9 +141,9 @@ abstract class LogFormatter implements LogFormatterInterface {
75
141
}
76
142
77
143
/**
78
- * Get a string containing the location of an error, given a particular stack trace.
144
+ * Get the location of an error from a stack trace.
79
145
*
80
- * @param { string } stack - stack trace
146
+ * @param stack - stack trace to parse
81
147
*/
82
148
public getCodeLocation ( stack ?: string ) : string {
83
149
if ( ! stack ) {
@@ -100,14 +166,16 @@ abstract class LogFormatter implements LogFormatterInterface {
100
166
101
167
/**
102
168
* Create a new Intl.DateTimeFormat object configured with the specified time zone
103
- * and formatting options. The time is displayed in 24-hour format (hour12: false).
169
+ * and formatting options.
170
+ *
171
+ * The time is displayed in 24-hour format (hour12: false).
104
172
*
105
- * @param { string } timeZone - IANA time zone identifier (e.g., "Asia/Dhaka").
173
+ * @param timezone - IANA time zone identifier (e.g., "Asia/Dhaka").
106
174
*/
107
- #getDateFormatter = ( timeZone : string ) : Intl . DateTimeFormat => {
175
+ #getDateFormatter = ( timezone : string ) : Intl . DateTimeFormat => {
108
176
const twoDigitFormatOption = '2-digit' ;
109
- const validTimeZone = Intl . supportedValuesOf ( 'timeZone' ) . includes ( timeZone )
110
- ? timeZone
177
+ const validTimeZone = Intl . supportedValuesOf ( 'timeZone' ) . includes ( timezone )
178
+ ? timezone
111
179
: 'UTC' ;
112
180
113
181
return new Intl . DateTimeFormat ( 'en' , {
@@ -125,12 +193,12 @@ abstract class LogFormatter implements LogFormatterInterface {
125
193
/**
126
194
* Generate an ISO 8601 timestamp string with the specified time zone and the local time zone offset.
127
195
*
128
- * @param { Date } date - date to format
129
- * @param { string } timeZone - IANA time zone identifier (e.g., "Asia/Dhaka").
196
+ * @param date - date to format
197
+ * @param timezone - IANA time zone identifier (e.g., "Asia/Dhaka").
130
198
*/
131
- #generateISOTimestampWithOffset( date : Date , timeZone : string ) : string {
199
+ #generateISOTimestampWithOffset( date : Date , timezone : string ) : string {
132
200
const { year, month, day, hour, minute, second } = this . #getDateFormatter(
133
- timeZone
201
+ timezone
134
202
)
135
203
. formatToParts ( date )
136
204
. reduce (
0 commit comments