Skip to content

Commit 7447594

Browse files
chore(lambda): validate logLevel with logFormat for advanced logging (#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*
2 parents be24aa5 + 3f43e62 commit 7447594

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

packages/aws-cdk-lib/aws-lambda/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ new lambda.Function(this, 'Lambda', {
173173
});
174174
```
175175

176+
To use `applicationLogLevel` and/or `systemLogLevel` you must set `logFormat` to `LogFormat.JSON`.
177+
176178
## Resource-based Policies
177179

178180
AWS Lambda supports resource-based policies for controlling access to Lambda

packages/aws-cdk-lib/aws-lambda/lib/function.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,10 @@ export class Function extends FunctionBase {
10851085
* function and undefined if not.
10861086
*/
10871087
private getLoggingConfig(props: FunctionProps): CfnFunction.LoggingConfigProperty | undefined {
1088+
if ((props.applicationLogLevel || props.systemLogLevel) && props.logFormat !== LogFormat.JSON) {
1089+
throw new Error(`To use ApplicationLogLevel and/or SystemLogLevel you must set LogFormat to '${LogFormat.JSON}', got '${props.logFormat}'.`);
1090+
}
1091+
10881092
let loggingConfig: CfnFunction.LoggingConfigProperty;
10891093
if (props.logFormat || props.logGroup) {
10901094
loggingConfig = {

packages/aws-cdk-lib/aws-lambda/test/logging-config.test.ts

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,60 @@ describe('logging Config', () => {
133133
logGroupName: 'customLogGroup',
134134
}),
135135
});
136-
}).toThrowError('CDK does not support setting logRetention and logGroup');
136+
}).toThrow(/CDK does not support setting logRetention and logGroup/);
137+
});
138+
139+
test('Throws when applicationLogLevel is specified with TEXT logFormat', () => {
140+
const app = new cdk.App();
141+
const stack = new cdk.Stack(app, 'stack');
142+
expect(() => {
143+
new lambda.Function(stack, 'Lambda', {
144+
code: new lambda.InlineCode('foo'),
145+
handler: 'index.handler',
146+
runtime: lambda.Runtime.NODEJS_18_X,
147+
logFormat: lambda.LogFormat.TEXT,
148+
applicationLogLevel: lambda.ApplicationLogLevel.INFO,
149+
});
150+
}).toThrow(/To use ApplicationLogLevel and\/or SystemLogLevel you must set LogFormat to 'JSON', got 'Text'./);
151+
});
152+
153+
test('Throws when systemLogLevel is specified with TEXT logFormat', () => {
154+
const app = new cdk.App();
155+
const stack = new cdk.Stack(app, 'stack');
156+
expect(() => {
157+
new lambda.Function(stack, 'Lambda', {
158+
code: new lambda.InlineCode('foo'),
159+
handler: 'index.handler',
160+
runtime: lambda.Runtime.NODEJS_18_X,
161+
logFormat: lambda.LogFormat.TEXT,
162+
systemLogLevel: lambda.SystemLogLevel.INFO,
163+
});
164+
}).toThrow(/To use ApplicationLogLevel and\/or SystemLogLevel you must set LogFormat to 'JSON', got 'Text'./);
165+
});
166+
167+
test('Throws when applicationLogLevel is specified if logFormat is undefined', () => {
168+
const app = new cdk.App();
169+
const stack = new cdk.Stack(app, 'stack');
170+
expect(() => {
171+
new lambda.Function(stack, 'Lambda', {
172+
code: new lambda.InlineCode('foo'),
173+
handler: 'index.handler',
174+
runtime: lambda.Runtime.NODEJS_18_X,
175+
applicationLogLevel: lambda.ApplicationLogLevel.INFO,
176+
});
177+
}).toThrow(/To use ApplicationLogLevel and\/or SystemLogLevel you must set LogFormat to 'JSON', got 'undefined'./);
178+
});
179+
180+
test('Throws when systemLogLevel is specified if logFormat is undefined', () => {
181+
const app = new cdk.App();
182+
const stack = new cdk.Stack(app, 'stack');
183+
expect(() => {
184+
new lambda.Function(stack, 'Lambda', {
185+
code: new lambda.InlineCode('foo'),
186+
handler: 'index.handler',
187+
runtime: lambda.Runtime.NODEJS_18_X,
188+
systemLogLevel: lambda.SystemLogLevel.INFO,
189+
});
190+
}).toThrow(/To use ApplicationLogLevel and\/or SystemLogLevel you must set LogFormat to 'JSON', got 'undefined'./);
137191
});
138192
});

0 commit comments

Comments
 (0)