diff --git a/packages/logger/src/Logger.ts b/packages/logger/src/Logger.ts index d9f732262d..b018543a27 100644 --- a/packages/logger/src/Logger.ts +++ b/packages/logger/src/Logger.ts @@ -282,13 +282,13 @@ class Logger implements ClassThatLogs { * @returns {HandlerMethodDecorator} */ public injectLambdaContext(): HandlerMethodDecorator { - return (target, propertyKey, descriptor) => { + return (target, _propertyKey, descriptor) => { const originalMethod = descriptor.value; descriptor.value = (event, context, callback) => { this.addContext(context); - return originalMethod?.apply(this, [ event, context, callback ]); + return originalMethod?.apply(target, [ event, context, callback ]); }; }; } diff --git a/packages/logger/tests/unit/Logger.test.ts b/packages/logger/tests/unit/Logger.test.ts index 93ed91b95c..8c3b04165d 100644 --- a/packages/logger/tests/unit/Logger.test.ts +++ b/packages/logger/tests/unit/Logger.test.ts @@ -605,6 +605,45 @@ describe('Class: Logger', () => { jest.spyOn(console, 'log').mockImplementation(() => {}); }); + test('when used as decorator, it returns a function with the correct scope of the decorated class', async () => { + + // Prepare + const logger = new Logger(); + class LambdaFunction implements LambdaInterface { + + @logger.injectLambdaContext() + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + public handler(_event: TEvent, _context: Context, _callback: Callback): void | Promise { + this.myClassMethod(); + } + + private myClassMethod (): void { + logger.info('This is an INFO log with some context'); + } + + } + + // Act + await new LambdaFunction().handler(dummyEvent, dummyContext, () => console.log('Lambda invoked!')); + + // Assess + expect(console['info']).toBeCalledTimes(1); + expect(console['info']).toHaveBeenNthCalledWith(1, JSON.stringify({ + cold_start: true, + function_arn: 'arn:aws:lambda:eu-central-1:123456789012:function:foo-bar-function', + function_memory_size: 128, + function_name: 'foo-bar-function', + function_request_id: 'c6af9ac6-7b61-11e6-9a41-93e812345678', + level: 'INFO', + message: 'This is an INFO log with some context', + service: 'hello-world', + timestamp: '2016-06-20T12:08:10.000Z', + xray_trace_id: 'abcdef123456abcdef123456abcdef123456', + })); + + }); + test('when used as decorator, it returns a function that captures Lambda\'s context information and adds it in the printed logs', async () => { // Prepare diff --git a/packages/logger/types/LambdaInterface.ts b/packages/logger/types/LambdaInterface.ts deleted file mode 100644 index b94b47b82b..0000000000 --- a/packages/logger/types/LambdaInterface.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { Handler } from 'aws-lambda'; - -interface LambdaInterface { - handler: Handler -} - -export { - LambdaInterface -}; \ No newline at end of file diff --git a/packages/logger/types/Logger.ts b/packages/logger/types/Logger.ts deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/metrics/src/Metrics.ts b/packages/metrics/src/Metrics.ts index 733ebcf80d..dba649700a 100644 --- a/packages/metrics/src/Metrics.ts +++ b/packages/metrics/src/Metrics.ts @@ -244,7 +244,7 @@ class Metrics implements MetricsInterface { let result: unknown; try { - result = await originalMethod?.apply(this, [ event, context, callback ]); + result = await originalMethod?.apply(target, [ event, context, callback ]); } catch (error) { throw error; } finally { diff --git a/packages/metrics/tests/unit/Metrics.test.ts b/packages/metrics/tests/unit/Metrics.test.ts index 4c9158b13f..1a1d0712c3 100644 --- a/packages/metrics/tests/unit/Metrics.test.ts +++ b/packages/metrics/tests/unit/Metrics.test.ts @@ -535,12 +535,43 @@ describe('Class: Metrics', () => { expect(loggedData[1]._aws.CloudWatchMetrics[0].Metrics.length).toBe(0); }); + test('Using decorator, it returns a function with the correct scope of the decorated class', async () => { + + // Prepare + const metrics = new Metrics({ namespace: 'test' }); + class LambdaFunction implements LambdaInterface { + @metrics.logMetrics({ defaultDimensions: { default: 'defaultValue' } }) + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + public async handler( + _event: TEvent, + _context: Context): Promise { + this.myMethod(); + + return 'Lambda invoked!'; + } + + private myMethod(): void { + metrics.addMetric('test_name', MetricUnits.Seconds, 10); + } + } + + // Act + await new LambdaFunction().handler(dummyEvent, dummyContext.helloworldContext); + + // Assess + expect(console.log).toBeCalledTimes(1); + + }); + test('Using decorator on async handler (without callback) should work fine', async () => { const metrics = new Metrics({ namespace: 'test' }); const additionalDimension = { name: 'metric2', value: 'metric2Value' }; class LambdaFunction implements LambdaInterface { @metrics.logMetrics({ defaultDimensions: { default: 'defaultValue' } }) + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore public async handler( _event: TEvent, _context: Context): Promise {