Skip to content

Commit 13b1d13

Browse files
authored
chore(logger): refactor types and interfaces (#1758)
* chore(logger): refactor types and interfaces * chore: grouped type files * chore: fix code smell * chore: fix ci * chore: fix ci
1 parent f89c795 commit 13b1d13

24 files changed

+610
-704
lines changed

Diff for: package-lock.json

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

+89-92
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,31 @@
1-
import { randomInt } from 'node:crypto';
2-
import { Console } from 'node:console';
3-
import type { Context, Handler } from 'aws-lambda';
41
import { Utility } from '@aws-lambda-powertools/commons';
5-
import { PowertoolsLogFormatter } from './formatter/PowertoolsLogFormatter.js';
6-
import { LogFormatterInterface } from './formatter/LogFormatterInterface.js';
7-
import { LogItem } from './log/LogItem.js';
2+
import type { HandlerMethodDecorator } from '@aws-lambda-powertools/commons/types';
3+
import type { Context, Handler } from 'aws-lambda';
84
import merge from 'lodash.merge';
9-
import { ConfigServiceInterface } from './config/ConfigServiceInterface.js';
5+
import { Console } from 'node:console';
6+
import { randomInt } from 'node:crypto';
107
import { EnvironmentVariablesService } from './config/EnvironmentVariablesService.js';
11-
import { LogJsonIndent } from './types/Logger.js';
8+
import { LogJsonIndent } from './constants.js';
9+
import { LogItem } from './formatter/LogItem.js';
10+
import { PowertoolsLogFormatter } from './formatter/PowertoolsLogFormatter.js';
11+
import type { ConfigServiceInterface } from './types/ConfigServiceInterface.js';
1212
import type {
1313
Environment,
1414
LogAttributes,
1515
LogLevel,
1616
LogLevelThresholds,
17+
LogFormatterInterface,
1718
} from './types/Log.js';
1819
import type {
19-
ClassThatLogs,
20-
HandlerMethodDecorator,
21-
LambdaFunctionContext,
20+
LogFunction,
2221
ConstructorOptions,
22+
InjectLambdaContextOptions,
2323
LogItemExtraInput,
2424
LogItemMessage,
25-
PowertoolLogData,
26-
HandlerOptions,
25+
LoggerInterface,
26+
PowertoolsLogData,
2727
} from './types/Logger.js';
28+
2829
/**
2930
* ## Intro
3031
* The Logger utility provides an opinionated logger with output structured as JSON.
@@ -111,7 +112,7 @@ import type {
111112
* @implements {ClassThatLogs}
112113
* @see https://docs.powertools.aws.dev/lambda-typescript/latest/core/logger/
113114
*/
114-
class Logger extends Utility implements ClassThatLogs {
115+
class Logger extends Utility implements LoggerInterface {
115116
/**
116117
* Console instance used to print logs.
117118
*
@@ -155,9 +156,9 @@ class Logger extends Utility implements ClassThatLogs {
155156
SILENT: 28,
156157
};
157158

158-
private persistentLogAttributes?: LogAttributes = {};
159+
private persistentLogAttributes: LogAttributes = {};
159160

160-
private powertoolLogData: PowertoolLogData = <PowertoolLogData>{};
161+
private powertoolsLogData: PowertoolsLogData = <PowertoolsLogData>{};
161162

162163
/**
163164
* Log level used by the current instance of Logger.
@@ -187,17 +188,15 @@ class Logger extends Utility implements ClassThatLogs {
187188
* @returns {void}
188189
*/
189190
public addContext(context: Context): void {
190-
const lambdaContext: Partial<LambdaFunctionContext> = {
191-
invokedFunctionArn: context.invokedFunctionArn,
192-
coldStart: this.getColdStart(),
193-
awsRequestId: context.awsRequestId,
194-
memoryLimitInMB: Number(context.memoryLimitInMB),
195-
functionName: context.functionName,
196-
functionVersion: context.functionVersion,
197-
};
198-
199-
this.addToPowertoolLogData({
200-
lambdaContext,
191+
this.addToPowertoolsLogData({
192+
lambdaContext: {
193+
invokedFunctionArn: context.invokedFunctionArn,
194+
coldStart: this.getColdStart(),
195+
awsRequestId: context.awsRequestId,
196+
memoryLimitInMB: context.memoryLimitInMB,
197+
functionName: context.functionName,
198+
functionVersion: context.functionVersion,
199+
},
201200
});
202201
}
203202

@@ -229,23 +228,27 @@ class Logger extends Utility implements ClassThatLogs {
229228
* @returns {Logger}
230229
*/
231230
public createChild(options: ConstructorOptions = {}): Logger {
232-
const parentsOptions = {
233-
logLevel: this.getLevelName(),
234-
customConfigService: this.getCustomConfigService(),
235-
logFormatter: this.getLogFormatter(),
236-
sampleRateValue: this.powertoolLogData.sampleRateValue,
237-
};
238-
const parentsPowertoolsLogData = this.getPowertoolLogData();
239231
const childLogger = this.createLogger(
240-
merge(parentsOptions, parentsPowertoolsLogData, options)
232+
// Merge parent logger options with options passed to createChild,
233+
// the latter having precedence.
234+
merge(
235+
{},
236+
{
237+
logLevel: this.getLevelName(),
238+
serviceName: this.powertoolsLogData.serviceName,
239+
sampleRateValue: this.powertoolsLogData.sampleRateValue,
240+
logFormatter: this.getLogFormatter(),
241+
customConfigService: this.getCustomConfigService(),
242+
environment: this.powertoolsLogData.environment,
243+
persistentLogAttributes: this.persistentLogAttributes,
244+
},
245+
options
246+
)
241247
);
242-
243-
const parentsPersistentLogAttributes = this.getPersistentLogAttributes();
244-
childLogger.addPersistentLogAttributes(parentsPersistentLogAttributes);
245-
246-
if (parentsPowertoolsLogData.lambdaContext) {
247-
childLogger.addContext(parentsPowertoolsLogData.lambdaContext as Context);
248-
}
248+
if (this.powertoolsLogData.lambdaContext)
249+
childLogger.addContext(
250+
this.powertoolsLogData.lambdaContext as unknown as Context
251+
);
249252

250253
return childLogger;
251254
}
@@ -315,7 +318,7 @@ class Logger extends Utility implements ClassThatLogs {
315318
* @returns {LogAttributes}
316319
*/
317320
public getPersistentLogAttributes(): LogAttributes {
318-
return this.persistentLogAttributes as LogAttributes;
321+
return this.persistentLogAttributes;
319322
}
320323

321324
/**
@@ -361,7 +364,9 @@ class Logger extends Utility implements ClassThatLogs {
361364
* @see https://www.typescriptlang.org/docs/handbook/decorators.html#method-decorators
362365
* @returns {HandlerMethodDecorator}
363366
*/
364-
public injectLambdaContext(options?: HandlerOptions): HandlerMethodDecorator {
367+
public injectLambdaContext(
368+
options?: InjectLambdaContextOptions
369+
): HandlerMethodDecorator {
365370
return (_target, _propertyKey, descriptor) => {
366371
/**
367372
* The descriptor.value is the method this decorator decorates, it cannot be undefined.
@@ -409,7 +414,7 @@ class Logger extends Utility implements ClassThatLogs {
409414
public static injectLambdaContextAfterOrOnError(
410415
logger: Logger,
411416
initialPersistentAttributes: LogAttributes,
412-
options?: HandlerOptions
417+
options?: InjectLambdaContextOptions
413418
): void {
414419
if (options && options.clearState === true) {
415420
logger.setPersistentLogAttributes(initialPersistentAttributes);
@@ -420,13 +425,13 @@ class Logger extends Utility implements ClassThatLogs {
420425
logger: Logger,
421426
event: unknown,
422427
context: Context,
423-
options?: HandlerOptions
428+
options?: InjectLambdaContextOptions
424429
): void {
425430
logger.addContext(context);
426431

427432
let shouldLogEvent = undefined;
428-
if (options && options.hasOwnProperty('logEvent')) {
429-
shouldLogEvent = options.logEvent;
433+
if (Object.hasOwn(options || {}, 'logEvent')) {
434+
shouldLogEvent = options!.logEvent;
430435
}
431436
logger.logEventIfEnabled(event, shouldLogEvent);
432437
}
@@ -439,9 +444,7 @@ class Logger extends Utility implements ClassThatLogs {
439444
* @returns {void}
440445
*/
441446
public logEventIfEnabled(event: unknown, overwriteValue?: boolean): void {
442-
if (!this.shouldLogEvent(overwriteValue)) {
443-
return;
444-
}
447+
if (!this.shouldLogEvent(overwriteValue)) return;
445448
this.info('Lambda invocation event', { event });
446449
}
447450

@@ -453,7 +456,7 @@ class Logger extends Utility implements ClassThatLogs {
453456
* @returns {void}
454457
*/
455458
public refreshSampleRateCalculation(): void {
456-
this.setInitialSampleRate(this.powertoolLogData.sampleRateValue);
459+
this.setInitialSampleRate(this.powertoolsLogData.sampleRateValue);
457460
}
458461

459462
/**
@@ -473,11 +476,11 @@ class Logger extends Utility implements ClassThatLogs {
473476
* @returns {void}
474477
*/
475478
public removePersistentLogAttributes(keys: string[]): void {
476-
keys.forEach((key) => {
477-
if (this.persistentLogAttributes && key in this.persistentLogAttributes) {
479+
for (const key of keys) {
480+
if (Object.hasOwn(this.persistentLogAttributes, key)) {
478481
delete this.persistentLogAttributes[key];
479482
}
480-
});
483+
}
481484
}
482485

483486
/**
@@ -559,16 +562,12 @@ class Logger extends Utility implements ClassThatLogs {
559562
/**
560563
* It stores information that is printed in all log items.
561564
*
562-
* @param {Partial<PowertoolLogData>} attributesArray
565+
* @param {Partial<PowertoolsLogData>} attributes
563566
* @private
564567
* @returns {void}
565568
*/
566-
private addToPowertoolLogData(
567-
...attributesArray: Array<Partial<PowertoolLogData>>
568-
): void {
569-
attributesArray.forEach((attributes: Partial<PowertoolLogData>) => {
570-
merge(this.powertoolLogData, attributes);
571-
});
569+
private addToPowertoolsLogData(attributes: Partial<PowertoolsLogData>): void {
570+
merge(this.powertoolsLogData, attributes);
572571
}
573572

574573
/**
@@ -595,7 +594,7 @@ class Logger extends Utility implements ClassThatLogs {
595594
message: typeof input === 'string' ? input : input.message,
596595
xRayTraceId: this.envVarsService.getXrayTraceId(),
597596
},
598-
this.getPowertoolLogData()
597+
this.getPowertoolsLogData()
599598
);
600599

601600
let additionalLogAttributes: LogAttributes = {};
@@ -665,15 +664,15 @@ class Logger extends Utility implements ClassThatLogs {
665664
* @returns - The name of the log level
666665
*/
667666
private getLogLevelNameFromNumber(logLevel: number): Uppercase<LogLevel> {
668-
const found = Object.entries(this.logLevelThresholds).find(
669-
([key, value]) => {
670-
if (value === logLevel) {
671-
return key;
672-
}
667+
let found;
668+
for (const [key, value] of Object.entries(this.logLevelThresholds)) {
669+
if (value === logLevel) {
670+
found = key;
671+
break;
673672
}
674-
)!;
673+
}
675674

676-
return found[0] as Uppercase<LogLevel>;
675+
return found as Uppercase<LogLevel>;
677676
}
678677

679678
/**
@@ -683,8 +682,8 @@ class Logger extends Utility implements ClassThatLogs {
683682
* @private
684683
* @returns {LogAttributes}
685684
*/
686-
private getPowertoolLogData(): PowertoolLogData {
687-
return this.powertoolLogData;
685+
private getPowertoolsLogData(): PowertoolsLogData {
686+
return this.powertoolsLogData;
688687
}
689688

690689
/**
@@ -765,7 +764,7 @@ class Logger extends Utility implements ClassThatLogs {
765764
logLevel === 24
766765
? 'error'
767766
: (this.getLogLevelNameFromNumber(logLevel).toLowerCase() as keyof Omit<
768-
ClassThatLogs,
767+
LogFunction,
769768
'critical'
770769
>);
771770

@@ -890,14 +889,14 @@ class Logger extends Utility implements ClassThatLogs {
890889
* @returns {void}
891890
*/
892891
private setInitialSampleRate(sampleRateValue?: number): void {
893-
this.powertoolLogData.sampleRateValue = 0;
892+
this.powertoolsLogData.sampleRateValue = 0;
894893
const constructorValue = sampleRateValue;
895894
const customConfigValue =
896895
this.getCustomConfigService()?.getSampleRateValue();
897896
const envVarsValue = this.getEnvVarsService().getSampleRateValue();
898897
for (const value of [constructorValue, customConfigValue, envVarsValue]) {
899898
if (this.isValidSampleRate(value)) {
900-
this.powertoolLogData.sampleRateValue = value;
899+
this.powertoolsLogData.sampleRateValue = value;
901900

902901
if (value && randomInt(0, 100) / 100 <= value) {
903902
this.setLogLevel('DEBUG');
@@ -972,7 +971,7 @@ class Logger extends Utility implements ClassThatLogs {
972971
this.setCustomConfigService(customConfigService);
973972
this.setInitialLogLevel(logLevel);
974973
this.setLogFormatter(logFormatter);
975-
this.setPowertoolLogData(serviceName, environment);
974+
this.setPowertoolsLogData(serviceName, environment);
976975
this.setInitialSampleRate(sampleRateValue);
977976
this.setLogEvent();
978977
this.setLogIndentation();
@@ -991,26 +990,24 @@ class Logger extends Utility implements ClassThatLogs {
991990
* @private
992991
* @returns {void}
993992
*/
994-
private setPowertoolLogData(
993+
private setPowertoolsLogData(
995994
serviceName?: string,
996995
environment?: Environment,
997996
persistentLogAttributes: LogAttributes = {}
998997
): void {
999-
this.addToPowertoolLogData(
1000-
{
1001-
awsRegion: this.getEnvVarsService().getAwsRegion(),
1002-
environment:
1003-
environment ||
1004-
this.getCustomConfigService()?.getCurrentEnvironment() ||
1005-
this.getEnvVarsService().getCurrentEnvironment(),
1006-
serviceName:
1007-
serviceName ||
1008-
this.getCustomConfigService()?.getServiceName() ||
1009-
this.getEnvVarsService().getServiceName() ||
1010-
this.getDefaultServiceName(),
1011-
},
1012-
persistentLogAttributes
1013-
);
998+
this.addToPowertoolsLogData({
999+
awsRegion: this.getEnvVarsService().getAwsRegion(),
1000+
environment:
1001+
environment ||
1002+
this.getCustomConfigService()?.getCurrentEnvironment() ||
1003+
this.getEnvVarsService().getCurrentEnvironment(),
1004+
serviceName:
1005+
serviceName ||
1006+
this.getCustomConfigService()?.getServiceName() ||
1007+
this.getEnvVarsService().getServiceName() ||
1008+
this.getDefaultServiceName(),
1009+
});
1010+
this.addPersistentLogAttributes(persistentLogAttributes);
10141011
}
10151012
}
10161013

Diff for: packages/logger/src/config/EnvironmentVariablesService.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ConfigServiceInterface } from './ConfigServiceInterface.js';
1+
import { ConfigServiceInterface } from '../types/ConfigServiceInterface.js';
22
import { EnvironmentVariablesService as CommonEnvironmentVariablesService } from '@aws-lambda-powertools/commons';
33

44
/**

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

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* The indent level for JSON logs.
3+
*
4+
* By default Logger will use the `LogJsonIndent.COMPACT` indent level, which
5+
* produces logs on a single line. This is the most efficient option for
6+
* CloudWatch Logs.
7+
*
8+
* When enabling the `POWERTOOLS_DEV` environment variable, Logger will use the
9+
* `LogJsonIndent.PRETTY` indent level, which indents the JSON logs for easier
10+
* reading.
11+
*/
12+
const LogJsonIndent = {
13+
PRETTY: 4,
14+
COMPACT: 0,
15+
} as const;
16+
17+
export { LogJsonIndent };

0 commit comments

Comments
 (0)