Skip to content

Commit b4568f9

Browse files
committed
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 7f0becd commit b4568f9

22 files changed

+601
-694
lines changed

packages/logger/src/Logger.ts

Lines changed: 90 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,32 @@
1-
import { randomInt } from 'node:crypto';
2-
import { Console } from 'node:console';
3-
import { format } from 'node:util';
4-
import type { Context, Handler } from 'aws-lambda';
51
import { Utility } from '@aws-lambda-powertools/commons';
6-
import { PowertoolsLogFormatter } from './formatter/PowertoolsLogFormatter.js';
7-
import { LogFormatterInterface } from './formatter/LogFormatterInterface.js';
8-
import { LogItem } from './log/LogItem.js';
2+
import type { HandlerMethodDecorator } from '@aws-lambda-powertools/commons/types';
3+
import type { Context, Handler } from 'aws-lambda';
94
import merge from 'lodash.merge';
10-
import { ConfigServiceInterface } from './config/ConfigServiceInterface.js';
5+
import { Console } from 'node:console';
6+
import { format } from 'node:util';
7+
import { randomInt } from 'node:crypto';
118
import { EnvironmentVariablesService } from './config/EnvironmentVariablesService.js';
12-
import { LogJsonIndent } from './types/Logger.js';
9+
import { LogJsonIndent } from './constants.js';
10+
import { LogItem } from './formatter/LogItem.js';
11+
import { PowertoolsLogFormatter } from './formatter/PowertoolsLogFormatter.js';
12+
import type { ConfigServiceInterface } from './types/ConfigServiceInterface.js';
1313
import type {
1414
Environment,
1515
LogAttributes,
1616
LogLevel,
1717
LogLevelThresholds,
18+
LogFormatterInterface,
1819
} from './types/Log.js';
1920
import type {
20-
ClassThatLogs,
21-
HandlerMethodDecorator,
22-
LambdaFunctionContext,
21+
LogFunction,
2322
ConstructorOptions,
23+
InjectLambdaContextOptions,
2424
LogItemExtraInput,
2525
LogItemMessage,
26-
PowertoolLogData,
27-
HandlerOptions,
26+
LoggerInterface,
27+
PowertoolsLogData,
2828
} from './types/Logger.js';
29+
2930
/**
3031
* ## Intro
3132
* The Logger utility provides an opinionated logger with output structured as JSON.
@@ -112,7 +113,7 @@ import type {
112113
* @implements {ClassThatLogs}
113114
* @see https://docs.powertools.aws.dev/lambda/typescript/latest/core/logger/
114115
*/
115-
class Logger extends Utility implements ClassThatLogs {
116+
class Logger extends Utility implements LoggerInterface {
116117
/**
117118
* Console instance used to print logs.
118119
*
@@ -156,9 +157,9 @@ class Logger extends Utility implements ClassThatLogs {
156157
SILENT: 28,
157158
};
158159

159-
private persistentLogAttributes?: LogAttributes = {};
160+
private persistentLogAttributes: LogAttributes = {};
160161

161-
private powertoolLogData: PowertoolLogData = <PowertoolLogData>{};
162+
private powertoolsLogData: PowertoolsLogData = <PowertoolsLogData>{};
162163

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

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

251254
return childLogger;
252255
}
@@ -316,7 +319,7 @@ class Logger extends Utility implements ClassThatLogs {
316319
* @returns {LogAttributes}
317320
*/
318321
public getPersistentLogAttributes(): LogAttributes {
319-
return this.persistentLogAttributes as LogAttributes;
322+
return this.persistentLogAttributes;
320323
}
321324

322325
/**
@@ -362,7 +365,9 @@ class Logger extends Utility implements ClassThatLogs {
362365
* @see https://www.typescriptlang.org/docs/handbook/decorators.html#method-decorators
363366
* @returns {HandlerMethodDecorator}
364367
*/
365-
public injectLambdaContext(options?: HandlerOptions): HandlerMethodDecorator {
368+
public injectLambdaContext(
369+
options?: InjectLambdaContextOptions
370+
): HandlerMethodDecorator {
366371
return (_target, _propertyKey, descriptor) => {
367372
/**
368373
* The descriptor.value is the method this decorator decorates, it cannot be undefined.
@@ -410,7 +415,7 @@ class Logger extends Utility implements ClassThatLogs {
410415
public static injectLambdaContextAfterOrOnError(
411416
logger: Logger,
412417
initialPersistentAttributes: LogAttributes,
413-
options?: HandlerOptions
418+
options?: InjectLambdaContextOptions
414419
): void {
415420
if (options && options.clearState === true) {
416421
logger.setPersistentLogAttributes(initialPersistentAttributes);
@@ -421,13 +426,13 @@ class Logger extends Utility implements ClassThatLogs {
421426
logger: Logger,
422427
event: unknown,
423428
context: Context,
424-
options?: HandlerOptions
429+
options?: InjectLambdaContextOptions
425430
): void {
426431
logger.addContext(context);
427432

428433
let shouldLogEvent = undefined;
429-
if (options && options.hasOwnProperty('logEvent')) {
430-
shouldLogEvent = options.logEvent;
434+
if (Object.hasOwn(options || {}, 'logEvent')) {
435+
shouldLogEvent = options!.logEvent;
431436
}
432437
logger.logEventIfEnabled(event, shouldLogEvent);
433438
}
@@ -440,9 +445,7 @@ class Logger extends Utility implements ClassThatLogs {
440445
* @returns {void}
441446
*/
442447
public logEventIfEnabled(event: unknown, overwriteValue?: boolean): void {
443-
if (!this.shouldLogEvent(overwriteValue)) {
444-
return;
445-
}
448+
if (!this.shouldLogEvent(overwriteValue)) return;
446449
this.info('Lambda invocation event', { event });
447450
}
448451

@@ -454,7 +457,7 @@ class Logger extends Utility implements ClassThatLogs {
454457
* @returns {void}
455458
*/
456459
public refreshSampleRateCalculation(): void {
457-
this.setInitialSampleRate(this.powertoolLogData.sampleRateValue);
460+
this.setInitialSampleRate(this.powertoolsLogData.sampleRateValue);
458461
}
459462

460463
/**
@@ -474,11 +477,11 @@ class Logger extends Utility implements ClassThatLogs {
474477
* @returns {void}
475478
*/
476479
public removePersistentLogAttributes(keys: string[]): void {
477-
keys.forEach((key) => {
478-
if (this.persistentLogAttributes && key in this.persistentLogAttributes) {
480+
for (const key of keys) {
481+
if (Object.hasOwn(this.persistentLogAttributes, key)) {
479482
delete this.persistentLogAttributes[key];
480483
}
481-
});
484+
}
482485
}
483486

484487
/**
@@ -564,16 +567,12 @@ class Logger extends Utility implements ClassThatLogs {
564567
/**
565568
* It stores information that is printed in all log items.
566569
*
567-
* @param {Partial<PowertoolLogData>} attributesArray
570+
* @param {Partial<PowertoolsLogData>} attributes
568571
* @private
569572
* @returns {void}
570573
*/
571-
private addToPowertoolLogData(
572-
...attributesArray: Array<Partial<PowertoolLogData>>
573-
): void {
574-
attributesArray.forEach((attributes: Partial<PowertoolLogData>) => {
575-
merge(this.powertoolLogData, attributes);
576-
});
574+
private addToPowertoolsLogData(attributes: Partial<PowertoolsLogData>): void {
575+
merge(this.powertoolsLogData, attributes);
577576
}
578577

579578
private awsLogLevelShortCircuit(selectedLogLevel?: string): boolean {
@@ -624,7 +623,7 @@ class Logger extends Utility implements ClassThatLogs {
624623
message: typeof input === 'string' ? input : input.message,
625624
xRayTraceId: this.envVarsService.getXrayTraceId(),
626625
},
627-
this.getPowertoolLogData()
626+
this.getPowertoolsLogData()
628627
);
629628

630629
let additionalLogAttributes: LogAttributes = {};
@@ -694,15 +693,15 @@ class Logger extends Utility implements ClassThatLogs {
694693
* @returns - The name of the log level
695694
*/
696695
private getLogLevelNameFromNumber(logLevel: number): Uppercase<LogLevel> {
697-
const found = Object.entries(this.logLevelThresholds).find(
698-
([key, value]) => {
699-
if (value === logLevel) {
700-
return key;
701-
}
696+
let found;
697+
for (const [key, value] of Object.entries(this.logLevelThresholds)) {
698+
if (value === logLevel) {
699+
found = key;
700+
break;
702701
}
703-
)!;
702+
}
704703

705-
return found[0] as Uppercase<LogLevel>;
704+
return found as Uppercase<LogLevel>;
706705
}
707706

708707
/**
@@ -712,8 +711,8 @@ class Logger extends Utility implements ClassThatLogs {
712711
* @private
713712
* @returns {LogAttributes}
714713
*/
715-
private getPowertoolLogData(): PowertoolLogData {
716-
return this.powertoolLogData;
714+
private getPowertoolsLogData(): PowertoolsLogData {
715+
return this.powertoolsLogData;
717716
}
718717

719718
/**
@@ -794,7 +793,7 @@ class Logger extends Utility implements ClassThatLogs {
794793
logLevel === 24
795794
? 'error'
796795
: (this.getLogLevelNameFromNumber(logLevel).toLowerCase() as keyof Omit<
797-
ClassThatLogs,
796+
LogFunction,
798797
'critical'
799798
>);
800799

@@ -923,14 +922,14 @@ class Logger extends Utility implements ClassThatLogs {
923922
* @returns {void}
924923
*/
925924
private setInitialSampleRate(sampleRateValue?: number): void {
926-
this.powertoolLogData.sampleRateValue = 0;
925+
this.powertoolsLogData.sampleRateValue = 0;
927926
const constructorValue = sampleRateValue;
928927
const customConfigValue =
929928
this.getCustomConfigService()?.getSampleRateValue();
930929
const envVarsValue = this.getEnvVarsService().getSampleRateValue();
931930
for (const value of [constructorValue, customConfigValue, envVarsValue]) {
932931
if (this.isValidSampleRate(value)) {
933-
this.powertoolLogData.sampleRateValue = value;
932+
this.powertoolsLogData.sampleRateValue = value;
934933

935934
if (value && randomInt(0, 100) / 100 <= value) {
936935
this.setLogLevel('DEBUG');
@@ -1005,7 +1004,7 @@ class Logger extends Utility implements ClassThatLogs {
10051004
this.setCustomConfigService(customConfigService);
10061005
this.setInitialLogLevel(logLevel);
10071006
this.setLogFormatter(logFormatter);
1008-
this.setPowertoolLogData(serviceName, environment);
1007+
this.setPowertoolsLogData(serviceName, environment);
10091008
this.setInitialSampleRate(sampleRateValue);
10101009
this.setLogEvent();
10111010
this.setLogIndentation();
@@ -1024,26 +1023,24 @@ class Logger extends Utility implements ClassThatLogs {
10241023
* @private
10251024
* @returns {void}
10261025
*/
1027-
private setPowertoolLogData(
1026+
private setPowertoolsLogData(
10281027
serviceName?: string,
10291028
environment?: Environment,
10301029
persistentLogAttributes: LogAttributes = {}
10311030
): void {
1032-
this.addToPowertoolLogData(
1033-
{
1034-
awsRegion: this.getEnvVarsService().getAwsRegion(),
1035-
environment:
1036-
environment ||
1037-
this.getCustomConfigService()?.getCurrentEnvironment() ||
1038-
this.getEnvVarsService().getCurrentEnvironment(),
1039-
serviceName:
1040-
serviceName ||
1041-
this.getCustomConfigService()?.getServiceName() ||
1042-
this.getEnvVarsService().getServiceName() ||
1043-
this.getDefaultServiceName(),
1044-
},
1045-
persistentLogAttributes
1046-
);
1031+
this.addToPowertoolsLogData({
1032+
awsRegion: this.getEnvVarsService().getAwsRegion(),
1033+
environment:
1034+
environment ||
1035+
this.getCustomConfigService()?.getCurrentEnvironment() ||
1036+
this.getEnvVarsService().getCurrentEnvironment(),
1037+
serviceName:
1038+
serviceName ||
1039+
this.getCustomConfigService()?.getServiceName() ||
1040+
this.getEnvVarsService().getServiceName() ||
1041+
this.getDefaultServiceName(),
1042+
});
1043+
this.addPersistentLogAttributes(persistentLogAttributes);
10471044
}
10481045
}
10491046

packages/logger/src/config/EnvironmentVariablesService.ts

Lines changed: 1 addition & 1 deletion
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
/**

packages/logger/src/constants.ts

Lines changed: 17 additions & 0 deletions
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)