diff --git a/package.json b/package.json index fa21e64e41..a8bf5cd517 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "scripts": { "commit": "commit", "lerna-ci": "lerna exec -- npm ci", - "lerna-test": "lerna exec -- jest --coverage --detectOpenHandles", + "lerna-test": "lerna exec -- npm run test", "lerna-build": "lerna exec -- tsc", "lerna-lint": "lerna exec -- eslint \"./{src,tests}/**/*.ts\"", "lerna-format": "lerna exec -- eslint --fix \"./{src,tests}/**/*.ts\"", diff --git a/packages/logger/README.md b/packages/logger/README.md index 1bd086ee49..2fe5a328f8 100644 --- a/packages/logger/README.md +++ b/packages/logger/README.md @@ -50,6 +50,8 @@ logger.error('This is an ERROR log'); ### Capturing Lambda context info +Without decorators: + ```typescript // Environment variables set for the Lambda process.env.LOG_LEVEL = 'WARN'; @@ -108,6 +110,51 @@ const lambdaHandler: Handler = async (event, context) => { +With decorators: + +```typescript +// Environment variables set for the Lambda +process.env.LOG_LEVEL = 'INFO'; +process.env.POWERTOOLS_SERVICE_NAME = 'hello-world'; + +const logger = new Logger(); + +class Lambda implements LambdaInterface { + + @logger.injectLambdaContext() + public handler(_event: TEvent, _context: Context, _callback: Callback): void | Promise { + + logger.info('This is an INFO log with some context'); + + } + +} + +new Lambda().handler(dummyEvent, dummyContext, () => console.log('Lambda invoked!')); + +``` + +
+ Click to expand and see the logs outputs + +```bash + +{ + aws_request_id: 'c6af9ac6-7b61-11e6-9a41-93e8deadbeef', + lambda_function_arn: 'arn:aws:lambda:eu-central-1:123456789012:function:Example', + lambda_function_memory_size: 128, + lambda_function_name: 'foo-bar-function', + level: 'INFO', + message: 'This is an INFO log with some context', + service: 'hello-world', + timestamp: '2021-03-17T08:25:41.198Z', + xray_trace_id: 'abcdef123456abcdef123456abcdef123456' +} + +``` +
+ + ### Appending additional keys ```typescript diff --git a/packages/logger/examples/child-logger.ts b/packages/logger/examples/child-logger.ts index dd54b9a4be..0910100b8b 100644 --- a/packages/logger/examples/child-logger.ts +++ b/packages/logger/examples/child-logger.ts @@ -30,4 +30,4 @@ const lambdaHandler: Handler = async () => { }; -lambdaHandler(dummyEvent, dummyContext, () => {}); \ No newline at end of file +lambdaHandler(dummyEvent, dummyContext, () => console.log('Lambda invoked!')); \ No newline at end of file diff --git a/packages/logger/examples/hello-world-with-context-decorators.ts b/packages/logger/examples/hello-world-with-context-decorators.ts new file mode 100644 index 0000000000..080cbabef7 --- /dev/null +++ b/packages/logger/examples/hello-world-with-context-decorators.ts @@ -0,0 +1,28 @@ +import { populateEnvironmentVariables } from '../tests/helpers'; + +// Populate runtime +populateEnvironmentVariables(); +// Additional runtime variables +process.env.LOG_LEVEL = 'INFO'; +process.env.POWERTOOLS_SERVICE_NAME = 'hello-world'; + +import * as dummyEvent from '../../../tests/resources/events/custom/hello-world.json'; +import { context as dummyContext } from '../../../tests/resources/contexts/hello-world'; +import { LambdaInterface } from '../src/lambda/LambdaInterface'; +import { Logger } from '../src'; +import { Callback, Context } from 'aws-lambda/handler'; + +const logger = new Logger(); + +class Lambda implements LambdaInterface { + + @logger.injectLambdaContext() + public handler(_event: TEvent, _context: Context, _callback: Callback): void | Promise { + + logger.info('This is an INFO log with some context'); + + } + +} + +new Lambda().handler(dummyEvent, dummyContext, () => console.log('Lambda invoked!')); \ No newline at end of file diff --git a/packages/logger/examples/sample-rate.ts b/packages/logger/examples/sample-rate.ts index 59049af7d3..72937304e3 100644 --- a/packages/logger/examples/sample-rate.ts +++ b/packages/logger/examples/sample-rate.ts @@ -27,4 +27,4 @@ const lambdaHandler: Handler = async () => { }; -lambdaHandler(dummyEvent, dummyContext, () => console.log('Lambda invoked!')); \ No newline at end of file +lambdaHandler(dummyEvent, dummyContext, () => console.log('lambda invoked!')); \ No newline at end of file diff --git a/packages/logger/jest.config.js b/packages/logger/jest.config.js index 9c42534a7f..6fbaae512f 100644 --- a/packages/logger/jest.config.js +++ b/packages/logger/jest.config.js @@ -22,10 +22,10 @@ module.exports = { ], 'coverageThreshold': { 'global': { - 'statements': 70, - 'branches': 60, - 'functions': 70, - 'lines': 70, + 'statements': 100, + 'branches': 100, + 'functions': 100, + 'lines': 100, }, }, 'coverageReporters': [ diff --git a/packages/logger/package.json b/packages/logger/package.json index ebdcb40c5b..0b981c9ff0 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -8,7 +8,7 @@ }, "scripts": { "commit": "commit", - "test": "jest --coverage --detectOpenHandles", + "test": "jest --detectOpenHandles", "watch": "jest --watch", "build": "tsc", "lint": "eslint \"./{src,tests}/**/*.ts\"", @@ -20,6 +20,7 @@ "postversion": "git push && git push --tags", "example:hello-world": "ts-node examples/hello-world.ts", "example:hello-world-with-context": "ts-node examples/hello-world-with-context.ts", + "example:hello-world-with-context-decorators": "ts-node examples/hello-world-with-context-decorators.ts", "example:custom-logger-options": "ts-node examples/custom-logger-options.ts", "example:child-logger": "ts-node examples/child-logger.ts", "example:additional-keys": "ts-node examples/additional-keys.ts", diff --git a/packages/logger/src/Logger.ts b/packages/logger/src/Logger.ts index d963a82fc8..e93267e9b2 100644 --- a/packages/logger/src/Logger.ts +++ b/packages/logger/src/Logger.ts @@ -4,34 +4,38 @@ import { LogItem } from './log'; import { cloneDeep, merge } from 'lodash/fp'; import { ConfigServiceInterface, EnvironmentVariablesService } from './config'; +import { LogFormatterInterface, PowertoolLogFormatter } from './formatter'; import { - Environment, - PowertoolAttributes, + PowertoolLogAttributes, LogAttributes, LoggerOptions, LogLevel, LogLevelThresholds, LambdaFunctionContext, LoggerInput, - LoggerExtraInput + LoggerExtraInput, + HandlerMethodDecorator } from '../types'; -import { LogFormatterInterface, PowertoolLogFormatter } from './formatter'; class Logger implements LoggerInterface { - private static coldStart: boolean = true; - - private customAttributes?: LogAttributes = {}; + private customAttributes: LogAttributes; private customConfigService?: ConfigServiceInterface; - private static readonly defaultLogLevel: LogLevel = 'INFO'; + private static readonly defaultIsContextEnabled: boolean = false; + + private static readonly defaultLogLevelThreshold: LogLevel = 'INFO'; - private envVarsService?: EnvironmentVariablesService; + private readonly envVarsService: EnvironmentVariablesService; - private logFormatter?: LogFormatterInterface; + private static isColdStart: boolean = true; - private logLevel?: LogLevel; + private isContextEnabled: boolean; + + private logFormatter: LogFormatterInterface; + + private logLevelThreshold: LogLevel; private readonly logLevelThresholds: LogLevelThresholds = { 'DEBUG' : 8, @@ -40,14 +44,47 @@ class Logger implements LoggerInterface { 'ERROR': 20 }; - private powertoolAttributes: PowertoolAttributes = {}; + private powertoolLogAttributes: PowertoolLogAttributes = {}; + + private sampleRateValue?: number; public constructor(options: LoggerOptions = {}) { - this.setOptions(options); + const { + logLevel, + serviceName, + sampleRateValue, + logFormatter, + customConfigService, + customAttributes, + environment, + isContextEnabled + } = options; + + this.customAttributes = this.pickValueWithDefault({}, customAttributes); + this.customConfigService = customConfigService; + this.envVarsService = new EnvironmentVariablesService(); + this.isContextEnabled = this.pickValueWithDefault( + Logger.defaultIsContextEnabled, + isContextEnabled, + this.getCustomConfigService()?.getIsContextEnabled(), + this.getEnvVarsService().getIsContextEnabled() + ); + this.logFormatter = this.pickValueWithDefault(new PowertoolLogFormatter(),logFormatter); + this.logLevelThreshold = this.pickValueWithDefault( + Logger.defaultLogLevelThreshold,logLevel, + this.getCustomConfigService()?.getLogLevel(), + this.getEnvVarsService().getLogLevel() + ); + this.sampleRateValue = this.pickValue( + sampleRateValue, + this.getCustomConfigService()?.getSampleRateValue(), + this.getEnvVarsService()?.getSampleRateValue() + ); + this.populatePowertoolLogAttributes(serviceName, environment); } public addContext(context: Context): void { - if (!this.isContextEnabled()) { + if (!this.getIsContextEnabled()) { return; } @@ -59,60 +96,99 @@ class Logger implements LoggerInterface { version: context.functionVersion, }; - this.addToPowertoolAttributes({ + this.addToPowertoolLogAttributes({ lambdaContext }); } public createChild(options: LoggerOptions = {}): Logger { - return cloneDeep(this).setOptions(options); + return cloneDeep(this).applyOptions(options); } public debug(input: LoggerInput, ...extraInput: LoggerExtraInput): void { - if (!this.shouldPrint('DEBUG')) { - return; - } - this.printLog('DEBUG', this.createLogItem('DEBUG', input, extraInput).getAttributes()); + this.processLogInputData('DEBUG', input, extraInput); } public error(input: LoggerInput, ...extraInput: LoggerExtraInput): void { - if (!this.shouldPrint('ERROR')) { - return; + this.processLogInputData('ERROR', input, extraInput); + } + + public static getIsColdStart(): boolean { + if (Logger.isColdStart === true) { + Logger.isColdStart = false; + + return true; } - this.printLog('ERROR', this.createLogItem('ERROR', input, extraInput).getAttributes()); + + return false; } public info(input: LoggerInput, ...extraInput: LoggerExtraInput): void { - if (!this.shouldPrint('INFO')) { - return; - } - this.printLog('INFO', this.createLogItem('INFO', input, extraInput).getAttributes()); + this.processLogInputData('INFO', input, extraInput); } - public static isColdStart(): boolean { - if (Logger.coldStart === true) { - Logger.coldStart = false; + public injectLambdaContext(enableContext: boolean = true): HandlerMethodDecorator { + return (target, propertyKey, descriptor ) => { + const originalMethod = descriptor.value; - return true; - } + descriptor.value = (event, context, callback) => { + this.setIsContextEnabled(enableContext); + this.addContext(context); + const result = originalMethod?.apply(this, [ event, context, callback ]); - return false; + return result; + }; + }; } public warn(input: LoggerInput, ...extraInput: LoggerExtraInput): void { - if (!this.shouldPrint('WARN')) { - return; - } - this.printLog('WARN', this.createLogItem('WARN', input, extraInput).getAttributes()); + this.processLogInputData('WARN', input, extraInput); } - private addToPowertoolAttributes(...attributesArray: Array>): void { - attributesArray.forEach((attributes: Partial) => { - this.powertoolAttributes = merge(this.getPowertoolAttributes(), attributes); + private addToPowertoolLogAttributes(...attributesArray: Array>): void { + attributesArray.forEach((attributes: Partial) => { + this.powertoolLogAttributes = merge(this.getPowertoolLogAttributes(), attributes); }); } + private applyOptions(options: LoggerOptions): Logger { + const { + logLevel, + serviceName, + sampleRateValue, + logFormatter, + customConfigService, + customAttributes, + environment, + isContextEnabled + } = options; + + if (customAttributes) { + this.setCustomAttributes(customAttributes); + } + if (customConfigService) { + this.setCustomConfigService(customConfigService); + } + if (isContextEnabled){ + this.setIsContextEnabled(isContextEnabled); + } + if (logFormatter) { + this.setLogFormatter(logFormatter); + } + if (logLevel) { + this.setLogLevelThreshold(logLevel); + } + if (sampleRateValue) { + this.setSampleRateValue(sampleRateValue); + } + if (serviceName || environment || isContextEnabled || customConfigService || logFormatter) { + this.populatePowertoolLogAttributes(serviceName, environment); + } + + return this; + } + private createLogItem(logLevel: LogLevel, input: LoggerInput, extraInput: LoggerExtraInput): LogItem { const logItem = new LogItem().addAttributes( @@ -122,7 +198,7 @@ class Logger implements LoggerInterface { timestamp: new Date(), message: (typeof input === 'string') ? input : input.message }, - this.getPowertoolAttributes()) + this.getPowertoolLogAttributes()) ) ).addAttributes(this.getCustomAttributes()); @@ -145,7 +221,7 @@ class Logger implements LoggerInterface { } private getCustomAttributes(): LogAttributes { - return this.customAttributes || {}; + return this.customAttributes; } private getCustomConfigService(): ConfigServiceInterface | undefined { @@ -153,123 +229,105 @@ class Logger implements LoggerInterface { } private getEnvVarsService(): EnvironmentVariablesService { - if (!this.envVarsService) { - this.setEnvVarsService(); - } + return this.envVarsService; + } - return this.envVarsService; + private getIsContextEnabled(): boolean { + return this.isContextEnabled; } private getLogFormatter(): LogFormatterInterface { - if (!this.logFormatter) { - this.setLogFormatter(); - } - - return this.logFormatter; + return this.logFormatter; } - private getLogLevel(): LogLevel { - if (this.powertoolAttributes?.logLevel) { - this.setLogLevel(); - } + private getLogLevelThreshold(): LogLevel { + return this.logLevelThreshold; + } - return this.logLevel; + private getPowertoolLogAttributes(): PowertoolLogAttributes { + return this.powertoolLogAttributes; } - private getPowertoolAttributes(): PowertoolAttributes { - return this.powertoolAttributes || {}; + private getSampleRateValue(): number | undefined { + return this.sampleRateValue; } - private getSampleRateValue(): number { - if (!this.powertoolAttributes?.sampleRateValue) { - this.setSampleRateValue(); + private pickValue(...values: Array): ValueType | undefined { + for (const entry of values) { + if (entry) { + return entry; + } } - return this.powertoolAttributes?.sampleRateValue; + return undefined; } - private isContextEnabled(): boolean { - return this.getCustomConfigService()?.getIsContextEnabled() === true || this.getEnvVarsService().getIsContextEnabled() === true; + private pickValueWithDefault(defaultValue: ValueType, ...values: Array): ValueType { + return this.pickValue(...values) || defaultValue; } - private printLog(logLevel: LogLevel, log: LogAttributes): void { - Object.keys(log).forEach(key => (log[key] === undefined || log[key] === '' || log[key] === null) && delete log[key]); + private populatePowertoolLogAttributes(serviceName?: string, environment?: string): void { - console.log(log); - } + this.addToPowertoolLogAttributes({ + awsRegion: this.getEnvVarsService().getAwsRegion(), + environment: this.pickValue(environment, this.getCustomConfigService()?.getCurrentEnvironment(), this.getEnvVarsService().getCurrentEnvironment()), + sampleRateValue: this.getSampleRateValue(), + serviceName: this.pickValue(serviceName,this.getCustomConfigService()?.getServiceName(), this.getEnvVarsService().getServiceName()), + xRayTraceId: this.getEnvVarsService().getXrayTraceId(), + }); - private setCustomAttributes(attributes?: LogAttributes): void { - this.customAttributes = attributes; + if (this.getIsContextEnabled()) { + this.addToPowertoolLogAttributes({ + lambdaContext: { + coldStart: Logger.getIsColdStart(), + memoryLimitInMB: this.getEnvVarsService().getFunctionMemory(), + name: this.getEnvVarsService().getFunctionName(), + version: this.getEnvVarsService().getFunctionVersion(), + } + }); + } } - private setCustomConfigService(customConfigService?: ConfigServiceInterface): void { - this.customConfigService = customConfigService? customConfigService : undefined; - } + private printLog(log: LogAttributes): void { + // TODO: revisit this + Object.keys(log).forEach(key => (log[key] === undefined || log[key] === '' || log[key] === null) && delete log[key]); - private setEnvVarsService(): void { - this.envVarsService = new EnvironmentVariablesService(); + console.log(log); } - private setLogFormatter(logFormatter?: LogFormatterInterface): void { - this.logFormatter = logFormatter || new PowertoolLogFormatter(); + private processLogInputData(logLevel: LogLevel, input: LoggerInput, extraInput: LoggerExtraInput): void { + if (!this.shouldPrint(logLevel)) { + return; + } + this.printLog(this.createLogItem(logLevel, input, extraInput).getAttributes()); } - private setLogLevel(logLevel?: LogLevel): void { - this.logLevel = (logLevel || this.getCustomConfigService()?.getLogLevel() || this.getEnvVarsService().getLogLevel() - || Logger.defaultLogLevel) as LogLevel; + private setCustomAttributes(attributes: LogAttributes): void { + this.customAttributes = attributes; } - private setOptions(options: LoggerOptions = {}): Logger { - const { - logLevel, - serviceName, - sampleRateValue, - logFormatter, - customConfigService, - customAttributes, - environment - } = options; - - this.setEnvVarsService(); - this.setCustomConfigService(customConfigService); - this.setLogLevel(logLevel); - this.setSampleRateValue(sampleRateValue); - this.setLogFormatter(logFormatter); - this.setPowertoolAttributes(serviceName, environment); - this.setCustomAttributes(customAttributes); - - return this; + private setCustomConfigService(customConfigService?: ConfigServiceInterface): void { + this.customConfigService = customConfigService; } - private setPowertoolAttributes(serviceName?: string, environment?: Environment, customAttributes: LogAttributes = {}): void { + private setIsContextEnabled(value: boolean = true): void { + this.isContextEnabled = value; + } - if (this.isContextEnabled()) { - this.addToPowertoolAttributes( { - lambdaContext: { - coldStart: Logger.isColdStart(), - memoryLimitInMB: this.getEnvVarsService().getFunctionMemory(), - name: this.getEnvVarsService().getFunctionName(), - version:this.getEnvVarsService().getFunctionVersion(), - } - }); - } + private setLogFormatter(value: LogFormatterInterface): void { + this.logFormatter = value; + } - this.addToPowertoolAttributes({ - awsRegion: this.getEnvVarsService().getAwsRegion(), - environment: environment || this.getCustomConfigService()?.getCurrentEnvironment() || this.getEnvVarsService().getCurrentEnvironment(), - sampleRateValue: this.getSampleRateValue(), - serviceName: serviceName || this.getCustomConfigService()?.getServiceName() || this.getEnvVarsService().getServiceName(), - xRayTraceId: this.getEnvVarsService().getXrayTraceId(), - }, customAttributes ); + private setLogLevelThreshold(value: LogLevel): void { + this.logLevelThreshold = value; } - private setSampleRateValue(sampleRateValue?: number): void { - this.powertoolAttributes.sampleRateValue = sampleRateValue || this.getCustomConfigService()?.getSampleRateValue() - || this.getEnvVarsService().getSampleRateValue(); + private setSampleRateValue(value?: number): void { + this.sampleRateValue = value; } private shouldPrint(logLevel: LogLevel): boolean { - if (this.logLevelThresholds[logLevel] >= this.logLevelThresholds[this.getLogLevel()]) { + if (this.logLevelThresholds[logLevel] >= this.logLevelThresholds[this.getLogLevelThreshold()]) { return true; } diff --git a/packages/logger/src/lambda/LambdaInterface.ts b/packages/logger/src/lambda/LambdaInterface.ts new file mode 100644 index 0000000000..6e31000601 --- /dev/null +++ b/packages/logger/src/lambda/LambdaInterface.ts @@ -0,0 +1,9 @@ +import { Handler } from 'aws-lambda'; + +interface LambdaInterface { + handler: Handler +} + +export { + LambdaInterface +}; \ No newline at end of file diff --git a/packages/logger/src/lambda/index.ts b/packages/logger/src/lambda/index.ts new file mode 100644 index 0000000000..059e4dbaf7 --- /dev/null +++ b/packages/logger/src/lambda/index.ts @@ -0,0 +1 @@ +export * from './LambdaInterface'; \ No newline at end of file diff --git a/packages/logger/tests/unit/Logger.test.ts b/packages/logger/tests/unit/Logger.test.ts index 5ed5cc910e..2ced521b64 100644 --- a/packages/logger/tests/unit/Logger.test.ts +++ b/packages/logger/tests/unit/Logger.test.ts @@ -1,3 +1,4 @@ +import { context as dummyContext } from '../../../../tests/resources/contexts/hello-world'; import { Logger } from '../../src'; import { populateEnvironmentVariables } from '../helpers'; @@ -55,8 +56,13 @@ describe('Logger', () => { logger.error('foo'); logger.error('foo', { bar: 'baz' }); + logger.error({ bar: 'baz', message: 'foo' }); - expect(console.log).toBeCalledTimes(2); + const error = new Error('Something happened!'); + error.stack = 'A custom stack trace'; + logger.error('foo', { bar: 'baz' }, error); + + expect(console.log).toBeCalledTimes(4); expect(console.log).toHaveBeenNthCalledWith(1, { message: 'foo', service: 'hello-world', @@ -72,6 +78,27 @@ describe('Logger', () => { timestamp: '2016-06-20T12:08:10.000Z', xray_trace_id: 'abcdef123456abcdef123456abcdef123456' }); + expect(console.log).toHaveBeenNthCalledWith(3, { + bar: 'baz', + message: 'foo', + service: 'hello-world', + level: 'ERROR', + timestamp: '2016-06-20T12:08:10.000Z', + xray_trace_id: 'abcdef123456abcdef123456abcdef123456' + }); + expect(console.log).toHaveBeenNthCalledWith(4, { + bar: 'baz', + error: { + message: 'Something happened!', + name: 'Error', + stack: 'A custom stack trace', + }, + message: 'foo', + service: 'hello-world', + level: 'ERROR', + timestamp: '2016-06-20T12:08:10.000Z', + xray_trace_id: 'abcdef123456abcdef123456abcdef123456' + }); }); test('should return a valid DEBUG log', () => { @@ -125,5 +152,44 @@ describe('Logger', () => { }); + test('should return a valid INFO log with context enabled', () => { + + const logger = new Logger({ + isContextEnabled: true + }); + logger.addContext(dummyContext); + + logger.info('foo'); + logger.info( { message: 'foo', bar: 'baz' }); + + expect(console.log).toBeCalledTimes(2); + expect(console.log).toHaveBeenNthCalledWith(1, { + 'aws_request_id': 'c6af9ac6-7b61-11e6-9a41-93e8deadbeef', + 'cold_start': true, + 'lambda_function_arn': 'arn:aws:lambda:eu-central-1:123456789012:function:Example', + 'lambda_function_memory_size': 128, + 'lambda_function_name': 'foo-bar-function', + 'level': 'INFO', + 'message': 'foo', + 'service': 'hello-world', + 'timestamp': '2016-06-20T12:08:10.000Z', + 'xray_trace_id': 'abcdef123456abcdef123456abcdef123456' + }); + expect(console.log).toHaveBeenNthCalledWith(2, { + 'aws_request_id': 'c6af9ac6-7b61-11e6-9a41-93e8deadbeef', + 'bar': 'baz', + 'cold_start': true, + 'lambda_function_arn': 'arn:aws:lambda:eu-central-1:123456789012:function:Example', + 'lambda_function_memory_size': 128, + 'lambda_function_name': 'foo-bar-function', + 'level': 'INFO', + 'message': 'foo', + 'service': 'hello-world', + 'timestamp': '2016-06-20T12:08:10.000Z', + 'xray_trace_id': 'abcdef123456abcdef123456abcdef123456' + }); + + }); + }); diff --git a/packages/logger/tsconfig.json b/packages/logger/tsconfig.json index 64b249fa6c..8c14301ecb 100644 --- a/packages/logger/tsconfig.json +++ b/packages/logger/tsconfig.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "experimentalDecorators": true, "noImplicitAny": true, "target": "ES2020", "module": "commonjs", diff --git a/packages/logger/types/Log.ts b/packages/logger/types/Log.ts index fba01ae081..b1f61e9998 100644 --- a/packages/logger/types/Log.ts +++ b/packages/logger/types/Log.ts @@ -3,7 +3,7 @@ type LogLevelInfo = 'INFO'; type LogLevelWarn = 'WARN'; type LogLevelError = 'ERROR'; -type LogLevel = LogLevelDebug | LogLevelInfo | LogLevelWarn | LogLevelError; +type LogLevel = LogLevelDebug | LogLevelInfo | LogLevelWarn | LogLevelError | string; type LogLevelThresholds = { [key in LogLevel]: number; diff --git a/packages/logger/types/Logger.ts b/packages/logger/types/Logger.ts index e322979f01..cea33eada8 100644 --- a/packages/logger/types/Logger.ts +++ b/packages/logger/types/Logger.ts @@ -1,4 +1,6 @@ import { ConfigServiceInterface } from '../src/config'; +import { Handler } from 'aws-lambda'; +import { LambdaInterface } from '../src/lambda'; import { LogFormatterInterface } from '../src/formatter'; import { Environment, LogAttributes, LogAttributesWithMessage, LogLevel } from './Log'; @@ -10,6 +12,7 @@ type LoggerOptions = { customConfigService?: ConfigServiceInterface customAttributes?: LogAttributes environment?: Environment + isContextEnabled?: boolean }; type LambdaFunctionContext = { @@ -21,7 +24,7 @@ type LambdaFunctionContext = { awsRequestId: string }; -type PowertoolAttributes = LogAttributes & { +type PowertoolLogAttributes = LogAttributes & { environment?: Environment serviceName: string sampleRateValue?: number @@ -30,7 +33,7 @@ type PowertoolAttributes = LogAttributes & { awsRegion: string }; -type UnformattedAttributes = PowertoolAttributes & { +type UnformattedAttributes = PowertoolLogAttributes & { environment?: Environment error?: Error serviceName: string @@ -46,11 +49,14 @@ type UnformattedAttributes = PowertoolAttributes & { type LoggerInput = string | LogAttributesWithMessage; type LoggerExtraInput = Array; +type HandlerMethodDecorator = (target: LambdaInterface, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor | void; + export { + HandlerMethodDecorator, LoggerInput, LoggerExtraInput, LambdaFunctionContext, UnformattedAttributes, - PowertoolAttributes, + PowertoolLogAttributes, LoggerOptions }; \ No newline at end of file diff --git a/packages/logger/types/formats/PowertoolLog.ts b/packages/logger/types/formats/PowertoolLog.ts index 9550916f07..dfb6f3ec18 100644 --- a/packages/logger/types/formats/PowertoolLog.ts +++ b/packages/logger/types/formats/PowertoolLog.ts @@ -1,4 +1,4 @@ -import { LogAttributes, LogLevel } from '../Log'; +import { LogAttributes, LogLevel } from '..'; type PowertoolLog = LogAttributes & {