Skip to content

Commit 8bcd2fc

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 cd46f5a commit 8bcd2fc

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';
@@ -627,16 +627,13 @@ class Logger extends Utility implements ClassThatLogs {
627627
this.getPowertoolLogData()
628628
);
629629

630-
const logItem = new LogItem({
631-
baseAttributes: this.getLogFormatter().formatAttributes(
632-
unformattedBaseAttributes
633-
),
634-
persistentAttributes: this.getPersistentLogAttributes(),
635-
});
636-
637-
// Add ephemeral attributes
630+
let additionalLogAttributes: LogAttributes = {};
631+
additionalLogAttributes = merge(
632+
additionalLogAttributes,
633+
this.getPersistentLogAttributes()
634+
);
638635
if (typeof input !== 'string') {
639-
logItem.addAttributes(input);
636+
additionalLogAttributes = merge(additionalLogAttributes, input);
640637
}
641638
extraInput.forEach((item: Error | LogAttributes | string) => {
642639
const attributes: LogAttributes =
@@ -646,9 +643,14 @@ class Logger extends Utility implements ClassThatLogs {
646643
? { extra: item }
647644
: item;
648645

649-
logItem.addAttributes(attributes);
646+
additionalLogAttributes = merge(additionalLogAttributes, attributes);
650647
});
651648

649+
const logItem = this.getLogFormatter().formatAttributes(
650+
unformattedBaseAttributes,
651+
additionalLogAttributes
652+
);
653+
652654
return logItem;
653655
}
654656

@@ -925,7 +927,7 @@ class Logger extends Utility implements ClassThatLogs {
925927
* @returns {void}
926928
*/
927929
private setLogFormatter(logFormatter?: LogFormatterInterface): void {
928-
this.logFormatter = logFormatter || new PowertoolLogFormatter();
930+
this.logFormatter = logFormatter || new PowertoolsLogFormatter();
929931
}
930932

931933
/**

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,
@@ -1601,7 +1601,7 @@ describe('Class: Logger', () => {
16011601
envVarsService: expect.any(EnvironmentVariablesService),
16021602
logEvent: false,
16031603
logIndentation: INDENTATION,
1604-
logFormatter: expect.any(PowertoolLogFormatter),
1604+
logFormatter: expect.any(PowertoolsLogFormatter),
16051605
logLevel: 8,
16061606
logLevelThresholds: {
16071607
...logLevelThresholds,
@@ -1624,7 +1624,7 @@ describe('Class: Logger', () => {
16241624
envVarsService: expect.any(EnvironmentVariablesService),
16251625
logEvent: false,
16261626
logIndentation: INDENTATION,
1627-
logFormatter: expect.any(PowertoolLogFormatter),
1627+
logFormatter: expect.any(PowertoolsLogFormatter),
16281628
logLevel: 8,
16291629
logLevelThresholds: {
16301630
...logLevelThresholds,
@@ -1647,7 +1647,7 @@ describe('Class: Logger', () => {
16471647
envVarsService: expect.any(EnvironmentVariablesService),
16481648
logEvent: false,
16491649
logIndentation: INDENTATION,
1650-
logFormatter: expect.any(PowertoolLogFormatter),
1650+
logFormatter: expect.any(PowertoolsLogFormatter),
16511651
logLevel: 8,
16521652
logLevelThresholds: {
16531653
...logLevelThresholds,
@@ -1713,7 +1713,7 @@ describe('Class: Logger', () => {
17131713
envVarsService: expect.any(EnvironmentVariablesService),
17141714
logEvent: false,
17151715
logIndentation: INDENTATION,
1716-
logFormatter: expect.any(PowertoolLogFormatter),
1716+
logFormatter: expect.any(PowertoolsLogFormatter),
17171717
logLevel: 8,
17181718
logLevelThresholds: {
17191719
...logLevelThresholds,
@@ -1736,7 +1736,7 @@ describe('Class: Logger', () => {
17361736
envVarsService: expect.any(EnvironmentVariablesService),
17371737
logEvent: false,
17381738
logIndentation: INDENTATION,
1739-
logFormatter: expect.any(PowertoolLogFormatter),
1739+
logFormatter: expect.any(PowertoolsLogFormatter),
17401740
logLevel: 8,
17411741
logLevelThresholds: {
17421742
...logLevelThresholds,
@@ -1762,7 +1762,7 @@ describe('Class: Logger', () => {
17621762
envVarsService: expect.any(EnvironmentVariablesService),
17631763
logEvent: false,
17641764
logIndentation: INDENTATION,
1765-
logFormatter: expect.any(PowertoolLogFormatter),
1765+
logFormatter: expect.any(PowertoolsLogFormatter),
17661766
logLevel: 8,
17671767
logLevelThresholds: {
17681768
...logLevelThresholds,
@@ -1785,7 +1785,7 @@ describe('Class: Logger', () => {
17851785
envVarsService: expect.any(EnvironmentVariablesService),
17861786
logEvent: false,
17871787
logIndentation: INDENTATION,
1788-
logFormatter: expect.any(PowertoolLogFormatter),
1788+
logFormatter: expect.any(PowertoolsLogFormatter),
17891789
logLevel: 20,
17901790
logLevelThresholds: {
17911791
...logLevelThresholds,
@@ -1829,7 +1829,7 @@ describe('Class: Logger', () => {
18291829
envVarsService: expect.any(EnvironmentVariablesService),
18301830
logEvent: false,
18311831
logIndentation: INDENTATION,
1832-
logFormatter: expect.any(PowertoolLogFormatter),
1832+
logFormatter: expect.any(PowertoolsLogFormatter),
18331833
logLevel: 8,
18341834
logLevelThresholds: {
18351835
...logLevelThresholds,
@@ -1852,7 +1852,7 @@ describe('Class: Logger', () => {
18521852
envVarsService: expect.any(EnvironmentVariablesService),
18531853
logEvent: false,
18541854
logIndentation: INDENTATION,
1855-
logFormatter: expect.any(PowertoolLogFormatter),
1855+
logFormatter: expect.any(PowertoolsLogFormatter),
18561856
logLevel: 8,
18571857
logLevelThresholds: {
18581858
...logLevelThresholds,
@@ -1882,7 +1882,7 @@ describe('Class: Logger', () => {
18821882
envVarsService: expect.any(EnvironmentVariablesService),
18831883
logEvent: false,
18841884
logIndentation: INDENTATION,
1885-
logFormatter: expect.any(PowertoolLogFormatter),
1885+
logFormatter: expect.any(PowertoolsLogFormatter),
18861886
logLevel: 8,
18871887
logLevelThresholds: {
18881888
...logLevelThresholds,
@@ -1923,7 +1923,7 @@ describe('Class: Logger', () => {
19231923
envVarsService: expect.any(EnvironmentVariablesService),
19241924
logEvent: false,
19251925
logIndentation: 0,
1926-
logFormatter: expect.any(PowertoolLogFormatter),
1926+
logFormatter: expect.any(PowertoolsLogFormatter),
19271927
logLevel: 8,
19281928
logLevelThresholds: {
19291929
...logLevelThresholds,
@@ -1950,7 +1950,7 @@ describe('Class: Logger', () => {
19501950

19511951
test('child logger should have the same logFormatter as its parent', () => {
19521952
// Prepare
1953-
class MyCustomLogFormatter extends PowertoolLogFormatter {}
1953+
class MyCustomLogFormatter extends PowertoolsLogFormatter {}
19541954
const parentLogger = new Logger({
19551955
logFormatter: new MyCustomLogFormatter(),
19561956
});
@@ -1968,7 +1968,7 @@ describe('Class: Logger', () => {
19681968

19691969
test('child logger with custom logFormatter in options should have provided logFormatter', () => {
19701970
// Prepare
1971-
class MyCustomLogFormatter extends PowertoolLogFormatter {}
1971+
class MyCustomLogFormatter extends PowertoolsLogFormatter {}
19721972
const parentLogger = new Logger();
19731973

19741974
// Act
@@ -1979,7 +1979,7 @@ describe('Class: Logger', () => {
19791979
// Assess
19801980
expect(parentLogger).toEqual(
19811981
expect.objectContaining({
1982-
logFormatter: expect.any(PowertoolLogFormatter),
1982+
logFormatter: expect.any(PowertoolsLogFormatter),
19831983
})
19841984
);
19851985

@@ -1992,7 +1992,7 @@ describe('Class: Logger', () => {
19921992

19931993
test('child logger should have exact same attributes as the parent logger created with all non-default options', () => {
19941994
// Prepare
1995-
class MyCustomLogFormatter extends PowertoolLogFormatter {}
1995+
class MyCustomLogFormatter extends PowertoolsLogFormatter {}
19961996
class MyCustomEnvironmentVariablesService extends EnvironmentVariablesService {}
19971997

19981998
const options: ConstructorOptions = {

0 commit comments

Comments
 (0)