Skip to content

Commit

Permalink
chore(lambda): validate logLevel with logFormat for advanced logging (#…
Browse files Browse the repository at this point in the history
…28045)

This PR adds to validate whether `applicationLogLevel` and
`systemLogLevel` have a JSON `logFormat` for advanced logging.

The doc states the following:

> To use log-level filtering, your function must be configured to use
the JSON log format. The default log format for all Lambda managed
runtimes is currently plain text. To learn how to configure your
function's log format to JSON, see [Setting your function's log
format](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs.html#monitoring-cloudwatchlogs-set-format).


https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs.html#monitoring-cloudwatchlogs-advanced

If you specify `systemLogLevel` or `applicationLogLevel` without
`LogFormat.JSON` like the following code, an error occurred in a CFn
event:
```
Resource handler returned message: "LogLevel is not supported when LogFormat is set to "Text". Remove LogLevel from your request or change the LogFormat to "Json" and try again.
```

```ts
new Function(stack, 'LambdaWithLogLevel', {
  code: new InlineCode('foo'),
  handler: 'index.handler',
  runtime: Runtime.NODEJS_18_X,
  logFormat: LogFormat.TEXT,
  systemLogLevel: SystemLogLevel.INFO,
  applicationLogLevel: ApplicationLogLevel.INFO,
});
```

This validation allows the error to be caught at the synth phase.

----

*By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache-2.0 license*
  • Loading branch information
sumupitchayan authored Nov 20, 2023
2 parents be24aa5 + 3f43e62 commit 7447594
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 1 deletion.
2 changes: 2 additions & 0 deletions packages/aws-cdk-lib/aws-lambda/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ new lambda.Function(this, 'Lambda', {
});
```

To use `applicationLogLevel` and/or `systemLogLevel` you must set `logFormat` to `LogFormat.JSON`.

## Resource-based Policies

AWS Lambda supports resource-based policies for controlling access to Lambda
Expand Down
4 changes: 4 additions & 0 deletions packages/aws-cdk-lib/aws-lambda/lib/function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,10 @@ export class Function extends FunctionBase {
* function and undefined if not.
*/
private getLoggingConfig(props: FunctionProps): CfnFunction.LoggingConfigProperty | undefined {
if ((props.applicationLogLevel || props.systemLogLevel) && props.logFormat !== LogFormat.JSON) {
throw new Error(`To use ApplicationLogLevel and/or SystemLogLevel you must set LogFormat to '${LogFormat.JSON}', got '${props.logFormat}'.`);
}

let loggingConfig: CfnFunction.LoggingConfigProperty;
if (props.logFormat || props.logGroup) {
loggingConfig = {
Expand Down
56 changes: 55 additions & 1 deletion packages/aws-cdk-lib/aws-lambda/test/logging-config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,60 @@ describe('logging Config', () => {
logGroupName: 'customLogGroup',
}),
});
}).toThrowError('CDK does not support setting logRetention and logGroup');
}).toThrow(/CDK does not support setting logRetention and logGroup/);
});

test('Throws when applicationLogLevel is specified with TEXT logFormat', () => {
const app = new cdk.App();
const stack = new cdk.Stack(app, 'stack');
expect(() => {
new lambda.Function(stack, 'Lambda', {
code: new lambda.InlineCode('foo'),
handler: 'index.handler',
runtime: lambda.Runtime.NODEJS_18_X,
logFormat: lambda.LogFormat.TEXT,
applicationLogLevel: lambda.ApplicationLogLevel.INFO,
});
}).toThrow(/To use ApplicationLogLevel and\/or SystemLogLevel you must set LogFormat to 'JSON', got 'Text'./);
});

test('Throws when systemLogLevel is specified with TEXT logFormat', () => {
const app = new cdk.App();
const stack = new cdk.Stack(app, 'stack');
expect(() => {
new lambda.Function(stack, 'Lambda', {
code: new lambda.InlineCode('foo'),
handler: 'index.handler',
runtime: lambda.Runtime.NODEJS_18_X,
logFormat: lambda.LogFormat.TEXT,
systemLogLevel: lambda.SystemLogLevel.INFO,
});
}).toThrow(/To use ApplicationLogLevel and\/or SystemLogLevel you must set LogFormat to 'JSON', got 'Text'./);
});

test('Throws when applicationLogLevel is specified if logFormat is undefined', () => {
const app = new cdk.App();
const stack = new cdk.Stack(app, 'stack');
expect(() => {
new lambda.Function(stack, 'Lambda', {
code: new lambda.InlineCode('foo'),
handler: 'index.handler',
runtime: lambda.Runtime.NODEJS_18_X,
applicationLogLevel: lambda.ApplicationLogLevel.INFO,
});
}).toThrow(/To use ApplicationLogLevel and\/or SystemLogLevel you must set LogFormat to 'JSON', got 'undefined'./);
});

test('Throws when systemLogLevel is specified if logFormat is undefined', () => {
const app = new cdk.App();
const stack = new cdk.Stack(app, 'stack');
expect(() => {
new lambda.Function(stack, 'Lambda', {
code: new lambda.InlineCode('foo'),
handler: 'index.handler',
runtime: lambda.Runtime.NODEJS_18_X,
systemLogLevel: lambda.SystemLogLevel.INFO,
});
}).toThrow(/To use ApplicationLogLevel and\/or SystemLogLevel you must set LogFormat to 'JSON', got 'undefined'./);
});
});

0 comments on commit 7447594

Please sign in to comment.