From 0e465bd23c7bd7e87fca8bc2811c02873fb2f65d Mon Sep 17 00:00:00 2001 From: Max Marze Date: Thu, 22 Feb 2024 15:40:51 -0500 Subject: [PATCH] feat: Support Lambda Logging Configuration (#12371) --- lib/plugins/aws/package/compile/functions.js | 22 ++++++++++++++++++- .../aws/package/lib/merge-iam-templates.js | 3 +++ lib/plugins/aws/provider.js | 17 ++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/lib/plugins/aws/package/compile/functions.js b/lib/plugins/aws/package/compile/functions.js index 93cbe699d..cbd8b5a64 100644 --- a/lib/plugins/aws/package/compile/functions.js +++ b/lib/plugins/aws/package/compile/functions.js @@ -440,7 +440,7 @@ class AwsCompileFunctions { functionResource.Properties.ReservedConcurrentExecutions = functionObject.reservedConcurrency; } - if (!functionObject.disableLogs) { + if (!functionObject.disableLogs && !functionObject?.logs?.logGroup && !this.serverless.service.provider.logs?.lambda?.logGroup) { functionResource.DependsOn = [this.provider.naming.getLogGroupLogicalId(functionName)].concat( functionResource.DependsOn || [] ); @@ -629,10 +629,30 @@ class AwsCompileFunctions { } } + if (functionObject.logs || this.serverless.service.provider.logs.lambda) { + const functionLogConfig = functionObject.logs + const providerLogConfig = this.serverless.service.provider.logs.lambda + const applicationLogLevel = functionLogConfig?.applicationLogLevel || providerLogConfig?.applicationLogLevel + const logFormat = functionLogConfig?.logFormat || providerLogConfig?.logFormat + const logGroup = functionLogConfig?.logGroup || providerLogConfig?.logGroup + const systemLogLevel = functionLogConfig?.systemLogLevel || providerLogConfig?.systemLogLevel + + const finalizedLogConfiguration = {} + if (applicationLogLevel && logFormat && logFormat === 'JSON') { finalizedLogConfiguration.ApplicationLogLevel = applicationLogLevel } + if (logFormat) { finalizedLogConfiguration.LogFormat = logFormat } + if (logGroup) { finalizedLogConfiguration.LogFormat = logGroup } + if (systemLogLevel && logFormat && logFormat === 'JSON') { finalizedLogConfiguration.SystemLogLevel = systemLogLevel } + + if (Object.keys(finalizedLogConfiguration).length > 0) { + functionResource.Properties.LoggingConfig = finalizedLogConfiguration + } + } + this.compileFunctionUrl(functionName); this.compileFunctionEventInvokeConfig(functionName); } + compileFunctionUrl(functionName) { const functionObject = this.serverless.service.getFunction(functionName); const cfTemplate = this.serverless.service.provider.compiledCloudFormationTemplate; diff --git a/lib/plugins/aws/package/lib/merge-iam-templates.js b/lib/plugins/aws/package/lib/merge-iam-templates.js index 3b2fffcfe..e349ef3f0 100644 --- a/lib/plugins/aws/package/lib/merge-iam-templates.js +++ b/lib/plugins/aws/package/lib/merge-iam-templates.js @@ -16,6 +16,9 @@ module.exports = { .filter((functionName) => !this.serverless.service.getFunction(functionName).disableLogs) .forEach((functionName) => { const functionObject = this.serverless.service.getFunction(functionName); + if (functionObject.logs?.logGroup || this.serverless.service.provider.logs?.lambda?.logGroup) { + return + } const logGroupLogicalId = this.provider.naming.getLogGroupLogicalId(functionName); const newLogGroup = { [logGroupLogicalId]: { diff --git a/lib/plugins/aws/provider.js b/lib/plugins/aws/provider.js index b5bb8e90e..52bf3fba8 100644 --- a/lib/plugins/aws/provider.js +++ b/lib/plugins/aws/provider.js @@ -715,6 +715,19 @@ class AwsProvider { 3288, 3653, ], }, + awsLambdaLoggingConfiguration: { + type: 'object', + properties: { + applicationLogLevel: { + type: 'string', + enum: ['DEBUG', 'ERROR', 'FATAL', 'INFO', 'TRACE', 'WARN'] + }, + logFormat: { type: 'string', enum: ['JSON', 'TRACE']}, + logGroup: { type: 'string', pattern: '[\\.\\-_/#A-Za-z0-9]+', minLength: 1, maxLength: 512}, + systemLogLevel: { type: 'string', enum: ['DEBUG', 'INFO', 'WARN'] } + }, + additionalProperties: false, + }, awsLogDataProtectionPolicy: { type: 'object', properties: { @@ -1163,6 +1176,7 @@ class AwsProvider { type: 'object', properties: { frameworkLambda: { type: 'boolean' }, + lambda: { $ref: '#/definitions/awsLambdaLoggingConfiguration' }, httpApi: { anyOf: [ { type: 'boolean' }, @@ -1443,6 +1457,9 @@ class AwsProvider { logDataProtectionPolicy: { $ref: '#/definitions/awsLogDataProtectionPolicy', }, + logs: { + $ref: '#/definitions/awsLambdaLoggingConfiguration' + }, maximumEventAge: { type: 'integer', minimum: 60, maximum: 21600 }, maximumRetryAttempts: { type: 'integer', minimum: 0, maximum: 2 }, memorySize: { $ref: '#/definitions/awsLambdaMemorySize' },