Skip to content

Commit 1e71c64

Browse files
erikayao93dreamorosi
authored andcommitted
feat(logger): Support for external observability providers (#1511)
* Updated formatAttributes for additional parameters and LogItem return type * Updated the unit tests to pass with new formatter * Updated Powertool named objects to Powertools * Updated tests to match new naming consistency * Updated for tests for new naming consistency * Updated formatter for new design decisions * Update Logger for ephemeral attributes * Update bringYourOwnFormatter documentation to match new formatter --------- Co-authored-by: erikayao93 <[email protected]>
1 parent 24b0ca1 commit 1e71c64

File tree

13 files changed

+133
-99
lines changed

13 files changed

+133
-99
lines changed

Diff for: docs/snippets/logger/bringYourOwnFormatterClass.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@ import {
33
LogAttributes,
44
UnformattedAttributes,
55
} from '@aws-lambda-powertools/logger/lib/types';
6+
import { LogItem } from '@aws-lambda-powertools/logger/lib/log';
67

78
// Replace this line with your own type
89
type MyCompanyLog = LogAttributes;
910

1011
class MyCompanyLogFormatter extends LogFormatter {
11-
public formatAttributes(attributes: UnformattedAttributes): MyCompanyLog {
12-
return {
12+
public formatAttributes(
13+
attributes: UnformattedAttributes,
14+
additionalLogAttributes: LogAttributes
15+
): LogItem {
16+
const baseAttributes: MyCompanyLog = {
1317
message: attributes.message,
1418
service: attributes.serviceName,
1519
environment: attributes.environment,
@@ -31,6 +35,11 @@ class MyCompanyLogFormatter extends LogFormatter {
3135
sampleRateValue: attributes.sampleRateValue,
3236
},
3337
};
38+
39+
const logItem = new LogItem({ attributes: baseAttributes });
40+
logItem.addAttributes(additionalLogAttributes); // add any attributes not explicitly defined
41+
42+
return logItem;
3443
}
3544
}
3645

Diff for: packages/logger/src/Logger.ts

+14-12
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { randomInt } from 'node:crypto';
22
import { Console } from 'node:console';
33
import type { Context, Handler } from 'aws-lambda';
44
import { Utility } from '@aws-lambda-powertools/commons';
5-
import { LogFormatterInterface, PowertoolLogFormatter } from './formatter';
5+
import { LogFormatterInterface, PowertoolsLogFormatter } from './formatter';
66
import { LogItem } from './log';
77
import merge from 'lodash.merge';
88
import { ConfigServiceInterface, EnvironmentVariablesService } from './config';
@@ -617,16 +617,13 @@ class Logger extends Utility implements ClassThatLogs {
617617
this.getPowertoolLogData()
618618
);
619619

620-
const logItem = new LogItem({
621-
baseAttributes: this.getLogFormatter().formatAttributes(
622-
unformattedBaseAttributes
623-
),
624-
persistentAttributes: this.getPersistentLogAttributes(),
625-
});
626-
627-
// Add ephemeral attributes
620+
let additionalLogAttributes: LogAttributes = {};
621+
additionalLogAttributes = merge(
622+
additionalLogAttributes,
623+
this.getPersistentLogAttributes()
624+
);
628625
if (typeof input !== 'string') {
629-
logItem.addAttributes(input);
626+
additionalLogAttributes = merge(additionalLogAttributes, input);
630627
}
631628
extraInput.forEach((item: Error | LogAttributes | string) => {
632629
const attributes: LogAttributes =
@@ -636,9 +633,14 @@ class Logger extends Utility implements ClassThatLogs {
636633
? { extra: item }
637634
: item;
638635

639-
logItem.addAttributes(attributes);
636+
additionalLogAttributes = merge(additionalLogAttributes, attributes);
640637
});
641638

639+
const logItem = this.getLogFormatter().formatAttributes(
640+
unformattedBaseAttributes,
641+
additionalLogAttributes
642+
);
643+
642644
return logItem;
643645
}
644646

@@ -915,7 +917,7 @@ class Logger extends Utility implements ClassThatLogs {
915917
* @returns {void}
916918
*/
917919
private setLogFormatter(logFormatter?: LogFormatterInterface): void {
918-
this.logFormatter = logFormatter || new PowertoolLogFormatter();
920+
this.logFormatter = logFormatter || new PowertoolsLogFormatter();
919921
}
920922

921923
/**

Diff for: packages/logger/src/formatter/LogFormatter.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { LogFormatterInterface } from '.';
22
import { LogAttributes, UnformattedAttributes } from '../types';
3+
import { LogItem } from '../log';
34

45
/**
56
* Typeguard to monkey patch Error to add a cause property.
@@ -30,11 +31,13 @@ abstract class LogFormatter implements LogFormatterInterface {
3031
* It formats key-value pairs of log attributes.
3132
*
3233
* @param {UnformattedAttributes} attributes
33-
* @returns {LogAttributes}
34+
* @param {LogAttributes} additionalLogAttributes
35+
* @returns {LogItem}
3436
*/
3537
public abstract formatAttributes(
36-
attributes: UnformattedAttributes
37-
): LogAttributes;
38+
attributes: UnformattedAttributes,
39+
additionalLogAttributes: LogAttributes
40+
): LogItem;
3841

3942
/**
4043
* It formats a given Error parameter.

Diff for: packages/logger/src/formatter/LogFormatterInterface.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { LogAttributes, UnformattedAttributes } from '../types';
2+
import { LogItem } from '../log';
23

34
/**
45
* @interface
@@ -8,9 +9,13 @@ interface LogFormatterInterface {
89
* It formats key-value pairs of log attributes.
910
*
1011
* @param {UnformattedAttributes} attributes
11-
* @returns {PowertoolLog}
12+
* @param {LogAttributes} additionalLogAttributes
13+
* @returns {LogItem}
1214
*/
13-
formatAttributes(attributes: UnformattedAttributes): LogAttributes;
15+
formatAttributes(
16+
attributes: UnformattedAttributes,
17+
additionalLogAttributes: LogAttributes
18+
): LogItem;
1419

1520
/**
1621
* It formats a given Error parameter.
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { LogFormatter } from '.';
2-
import { UnformattedAttributes } from '../types';
3-
import { PowertoolLog } from '../types/formats';
2+
import { LogAttributes, UnformattedAttributes } from '../types';
3+
import { PowertoolsLog } from '../types/formats';
4+
import { LogItem } from '../log';
45

56
/**
67
* This class is used to transform a set of log key-value pairs
@@ -9,15 +10,19 @@ import { PowertoolLog } from '../types/formats';
910
* @class
1011
* @extends {LogFormatter}
1112
*/
12-
class PowertoolLogFormatter extends LogFormatter {
13+
class PowertoolsLogFormatter extends LogFormatter {
1314
/**
1415
* It formats key-value pairs of log attributes.
1516
*
1617
* @param {UnformattedAttributes} attributes
17-
* @returns {PowertoolLog}
18+
* @param {LogAttributes} additionalLogAttributes
19+
* @returns {PowertoolsLog}
1820
*/
19-
public formatAttributes(attributes: UnformattedAttributes): PowertoolLog {
20-
return {
21+
public formatAttributes(
22+
attributes: UnformattedAttributes,
23+
additionalLogAttributes: LogAttributes
24+
): LogItem {
25+
const baseAttributes: PowertoolsLog = {
2126
cold_start: attributes.lambdaContext?.coldStart,
2227
function_arn: attributes.lambdaContext?.invokedFunctionArn,
2328
function_memory_size: attributes.lambdaContext?.memoryLimitInMB,
@@ -30,7 +35,13 @@ class PowertoolLogFormatter extends LogFormatter {
3035
timestamp: this.formatTimestamp(attributes.timestamp),
3136
xray_trace_id: attributes.xRayTraceId,
3237
};
38+
39+
const powertoolLogItem = new LogItem({ attributes: baseAttributes });
40+
41+
powertoolLogItem.addAttributes(additionalLogAttributes);
42+
43+
return powertoolLogItem;
3344
}
3445
}
3546

36-
export { PowertoolLogFormatter };
47+
export { PowertoolsLogFormatter };

Diff for: packages/logger/src/formatter/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
export * from './LogFormatter';
22
export * from './LogFormatterInterface';
3-
export * from './PowertoolLogFormatter';
3+
export * from './PowertoolsLogFormatter';

Diff for: packages/logger/src/log/LogItem.ts

+3-7
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,12 @@ import { LogAttributes } from '../types';
55
class LogItem implements LogItemInterface {
66
private attributes: LogAttributes = {};
77

8-
public constructor(params: {
9-
baseAttributes: LogAttributes;
10-
persistentAttributes: LogAttributes;
11-
}) {
8+
public constructor(params: { attributes: LogAttributes }) {
129
// Add attributes in the log item in this order:
1310
// - Base attributes supported by the Powertool by default
14-
// - Persistent attributes provided by developer, not formatted
11+
// - Persistent attributes provided by developer, not formatted (done later)
1512
// - Ephemeral attributes provided as parameters for a single log item (done later)
16-
this.addAttributes(params.baseAttributes);
17-
this.addAttributes(params.persistentAttributes);
13+
this.addAttributes(params.attributes);
1814
}
1915

2016
public addAttributes(attributes: LogAttributes): LogItem {

Diff for: packages/logger/src/types/formats/PowertoolLog.ts renamed to packages/logger/src/types/formats/PowertoolsLog.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { LogAttributes, LogLevel } from '..';
22

3-
type PowertoolLog = LogAttributes & {
3+
type PowertoolsLog = LogAttributes & {
44
/**
55
* timestamp
66
*
@@ -90,4 +90,4 @@ type PowertoolLog = LogAttributes & {
9090
lambda_request_id?: string;
9191
};
9292

93-
export type { PowertoolLog };
93+
export type { PowertoolsLog };

Diff for: packages/logger/src/types/formats/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from './PowertoolLog';
1+
export * from './PowertoolsLog';

Diff for: packages/logger/tests/unit/Logger.test.ts

+17-17
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
} from '@aws-lambda-powertools/commons';
1111
import { createLogger, Logger } from '../../src';
1212
import { EnvironmentVariablesService } from '../../src/config';
13-
import { PowertoolLogFormatter } from '../../src/formatter';
13+
import { PowertoolsLogFormatter } from '../../src/formatter';
1414
import {
1515
ClassThatLogs,
1616
LogJsonIndent,
@@ -798,7 +798,7 @@ describe('Class: Logger', () => {
798798
envVarsService: expect.any(EnvironmentVariablesService),
799799
logEvent: false,
800800
logIndentation: 0,
801-
logFormatter: expect.any(PowertoolLogFormatter),
801+
logFormatter: expect.any(PowertoolsLogFormatter),
802802
logLevel: 8,
803803
logLevelThresholds: {
804804
...logLevelThresholds,
@@ -1621,7 +1621,7 @@ describe('Class: Logger', () => {
16211621
envVarsService: expect.any(EnvironmentVariablesService),
16221622
logEvent: false,
16231623
logIndentation: INDENTATION,
1624-
logFormatter: expect.any(PowertoolLogFormatter),
1624+
logFormatter: expect.any(PowertoolsLogFormatter),
16251625
logLevel: 8,
16261626
logLevelThresholds: {
16271627
...logLevelThresholds,
@@ -1644,7 +1644,7 @@ describe('Class: Logger', () => {
16441644
envVarsService: expect.any(EnvironmentVariablesService),
16451645
logEvent: false,
16461646
logIndentation: INDENTATION,
1647-
logFormatter: expect.any(PowertoolLogFormatter),
1647+
logFormatter: expect.any(PowertoolsLogFormatter),
16481648
logLevel: 8,
16491649
logLevelThresholds: {
16501650
...logLevelThresholds,
@@ -1667,7 +1667,7 @@ describe('Class: Logger', () => {
16671667
envVarsService: expect.any(EnvironmentVariablesService),
16681668
logEvent: false,
16691669
logIndentation: INDENTATION,
1670-
logFormatter: expect.any(PowertoolLogFormatter),
1670+
logFormatter: expect.any(PowertoolsLogFormatter),
16711671
logLevel: 8,
16721672
logLevelThresholds: {
16731673
...logLevelThresholds,
@@ -1733,7 +1733,7 @@ describe('Class: Logger', () => {
17331733
envVarsService: expect.any(EnvironmentVariablesService),
17341734
logEvent: false,
17351735
logIndentation: INDENTATION,
1736-
logFormatter: expect.any(PowertoolLogFormatter),
1736+
logFormatter: expect.any(PowertoolsLogFormatter),
17371737
logLevel: 8,
17381738
logLevelThresholds: {
17391739
...logLevelThresholds,
@@ -1756,7 +1756,7 @@ describe('Class: Logger', () => {
17561756
envVarsService: expect.any(EnvironmentVariablesService),
17571757
logEvent: false,
17581758
logIndentation: INDENTATION,
1759-
logFormatter: expect.any(PowertoolLogFormatter),
1759+
logFormatter: expect.any(PowertoolsLogFormatter),
17601760
logLevel: 8,
17611761
logLevelThresholds: {
17621762
...logLevelThresholds,
@@ -1782,7 +1782,7 @@ describe('Class: Logger', () => {
17821782
envVarsService: expect.any(EnvironmentVariablesService),
17831783
logEvent: false,
17841784
logIndentation: INDENTATION,
1785-
logFormatter: expect.any(PowertoolLogFormatter),
1785+
logFormatter: expect.any(PowertoolsLogFormatter),
17861786
logLevel: 8,
17871787
logLevelThresholds: {
17881788
...logLevelThresholds,
@@ -1805,7 +1805,7 @@ describe('Class: Logger', () => {
18051805
envVarsService: expect.any(EnvironmentVariablesService),
18061806
logEvent: false,
18071807
logIndentation: INDENTATION,
1808-
logFormatter: expect.any(PowertoolLogFormatter),
1808+
logFormatter: expect.any(PowertoolsLogFormatter),
18091809
logLevel: 20,
18101810
logLevelThresholds: {
18111811
...logLevelThresholds,
@@ -1849,7 +1849,7 @@ describe('Class: Logger', () => {
18491849
envVarsService: expect.any(EnvironmentVariablesService),
18501850
logEvent: false,
18511851
logIndentation: INDENTATION,
1852-
logFormatter: expect.any(PowertoolLogFormatter),
1852+
logFormatter: expect.any(PowertoolsLogFormatter),
18531853
logLevel: 8,
18541854
logLevelThresholds: {
18551855
...logLevelThresholds,
@@ -1872,7 +1872,7 @@ describe('Class: Logger', () => {
18721872
envVarsService: expect.any(EnvironmentVariablesService),
18731873
logEvent: false,
18741874
logIndentation: INDENTATION,
1875-
logFormatter: expect.any(PowertoolLogFormatter),
1875+
logFormatter: expect.any(PowertoolsLogFormatter),
18761876
logLevel: 8,
18771877
logLevelThresholds: {
18781878
...logLevelThresholds,
@@ -1902,7 +1902,7 @@ describe('Class: Logger', () => {
19021902
envVarsService: expect.any(EnvironmentVariablesService),
19031903
logEvent: false,
19041904
logIndentation: INDENTATION,
1905-
logFormatter: expect.any(PowertoolLogFormatter),
1905+
logFormatter: expect.any(PowertoolsLogFormatter),
19061906
logLevel: 8,
19071907
logLevelThresholds: {
19081908
...logLevelThresholds,
@@ -1943,7 +1943,7 @@ describe('Class: Logger', () => {
19431943
envVarsService: expect.any(EnvironmentVariablesService),
19441944
logEvent: false,
19451945
logIndentation: 0,
1946-
logFormatter: expect.any(PowertoolLogFormatter),
1946+
logFormatter: expect.any(PowertoolsLogFormatter),
19471947
logLevel: 8,
19481948
logLevelThresholds: {
19491949
...logLevelThresholds,
@@ -1970,7 +1970,7 @@ describe('Class: Logger', () => {
19701970

19711971
test('child logger should have the same logFormatter as its parent', () => {
19721972
// Prepare
1973-
class MyCustomLogFormatter extends PowertoolLogFormatter {}
1973+
class MyCustomLogFormatter extends PowertoolsLogFormatter {}
19741974
const parentLogger = new Logger({
19751975
logFormatter: new MyCustomLogFormatter(),
19761976
});
@@ -1988,7 +1988,7 @@ describe('Class: Logger', () => {
19881988

19891989
test('child logger with custom logFormatter in options should have provided logFormatter', () => {
19901990
// Prepare
1991-
class MyCustomLogFormatter extends PowertoolLogFormatter {}
1991+
class MyCustomLogFormatter extends PowertoolsLogFormatter {}
19921992
const parentLogger = new Logger();
19931993

19941994
// Act
@@ -1999,7 +1999,7 @@ describe('Class: Logger', () => {
19991999
// Assess
20002000
expect(parentLogger).toEqual(
20012001
expect.objectContaining({
2002-
logFormatter: expect.any(PowertoolLogFormatter),
2002+
logFormatter: expect.any(PowertoolsLogFormatter),
20032003
})
20042004
);
20052005

@@ -2012,7 +2012,7 @@ describe('Class: Logger', () => {
20122012

20132013
test('child logger should have exact same attributes as the parent logger created with all non-default options', () => {
20142014
// Prepare
2015-
class MyCustomLogFormatter extends PowertoolLogFormatter {}
2015+
class MyCustomLogFormatter extends PowertoolsLogFormatter {}
20162016
class MyCustomEnvironmentVariablesService extends EnvironmentVariablesService {}
20172017

20182018
const options: ConstructorOptions = {

0 commit comments

Comments
 (0)