From c540811597a947bda329db0f0af3d8dd28c63ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Forestier?= Date: Mon, 5 Aug 2024 16:20:04 +0200 Subject: [PATCH] Add LoggingConfiguration parameter for lambda function This new parameter configure logging format and level for cloudwatch. This allow to change lambda function's verbosity from the AWS console without updating stack with new code if log format is set to JSON. ref no-issue --- src/e3/aws/troposphere/awslambda/__init__.py | 14 ++++++++++++++ src/e3/aws/troposphere/awslambda/flask.py | 6 ++++++ .../troposphere/awslambda/awslambda_test.py | 11 +++++++++++ 3 files changed, 31 insertions(+) diff --git a/src/e3/aws/troposphere/awslambda/__init__.py b/src/e3/aws/troposphere/awslambda/__init__.py index 1947aba..a235e09 100644 --- a/src/e3/aws/troposphere/awslambda/__init__.py +++ b/src/e3/aws/troposphere/awslambda/__init__.py @@ -46,6 +46,7 @@ def __init__( logs_retention_in_days: int | None = 731, reserved_concurrent_executions: int | None = None, environment: dict[str, str] | None = None, + logging_config: awslambda.LoggingConfig | None = None, ): """Initialize an AWS lambda function. @@ -71,6 +72,7 @@ def __init__( that are reserved for this function :param environment: Environment variables that are accessible from function code during execution + :param logging_config: The function's Amazon CloudWatch Logs settings """ self.name = name self.description = description @@ -87,6 +89,7 @@ def __init__( self.logs_retention_in_days = logs_retention_in_days self.reserved_concurrent_executions = reserved_concurrent_executions self.environment = environment + self.logging_config = logging_config def cfn_policy_document(self, stack: Stack) -> PolicyDocument: statements = [ @@ -196,6 +199,9 @@ def lambda_resources( if self.reserved_concurrent_executions is not None: params["ReservedConcurrentExecutions"] = self.reserved_concurrent_executions + if self.logging_config is not None: + params["LoggingConfig"] = self.logging_config + result = [awslambda.Function(name_to_id(self.name), **params)] # If retention duration is given provide a log group. # If not provided the lambda creates a log group with @@ -278,6 +284,7 @@ def __init__( image_tag: str, timeout: int = 3, memory_size: int | None = None, + logging_config: awslambda.LoggingConfig | None = None, ): """Initialize an AWS lambda function using a Docker image. @@ -290,6 +297,7 @@ def __init__( :param timeout: maximum execution time (default: 3s) :param memory_size: the amount of memory available to the function at runtime. The value can be any multiple of 1 MB. + :param logging_config: The function's Amazon CloudWatch Logs settings """ super().__init__( name=name, @@ -297,6 +305,7 @@ def __init__( role=role, timeout=timeout, memory_size=memory_size, + logging_config=logging_config, ) self.source_dir: str = source_dir self.repository_name: str = repository_name @@ -354,6 +363,7 @@ def __init__( logs_retention_in_days: int | None = 731, reserved_concurrent_executions: int | None = None, environment: dict[str, str] | None = None, + logging_config: awslambda.LoggingConfig | None = None, ): """Initialize an AWS lambda function with a Python runtime. @@ -379,6 +389,7 @@ def __init__( that are reserved for this function :param environment: Environment variables that are accessible from function code during execution + :param logging_config: The function's Amazon CloudWatch Logs settings """ assert runtime.startswith("python"), "PyFunction only accept Python runtimes" super().__init__( @@ -396,6 +407,7 @@ def __init__( logs_retention_in_days=logs_retention_in_days, reserved_concurrent_executions=reserved_concurrent_executions, environment=environment, + logging_config=logging_config, ) self.code_dir = code_dir self.requirement_file = requirement_file @@ -478,6 +490,7 @@ def __init__( ephemeral_storage_size: int | None = None, logs_retention_in_days: int | None = None, reserved_concurrent_executions: int | None = None, + logging_config: awslambda.LoggingConfig | None = None, ): """Initialize an AWS lambda function using Python 3.8 runtime. @@ -497,6 +510,7 @@ def __init__( ephemeral_storage_size=ephemeral_storage_size, logs_retention_in_days=logs_retention_in_days, reserved_concurrent_executions=reserved_concurrent_executions, + logging_config=logging_config, ) diff --git a/src/e3/aws/troposphere/awslambda/flask.py b/src/e3/aws/troposphere/awslambda/flask.py index 8c1b4a2..a70f8ce 100644 --- a/src/e3/aws/troposphere/awslambda/flask.py +++ b/src/e3/aws/troposphere/awslambda/flask.py @@ -33,6 +33,7 @@ def hello_world(): import os from troposphere import GetAtt +from troposphere.awslambda import LoggingConfig from e3.aws.troposphere.iam.role import Role from e3.fs import cp, sync_tree from . import PyFunction @@ -65,6 +66,7 @@ def __init__( logs_retention_in_days: int | None = 731, reserved_concurrent_executions: int | None = None, environment: dict[str, str] | None = None, + logging_config: LoggingConfig | None = None, ): """Initialize a Flask AWS lambda function using a Python runtime. @@ -87,6 +89,7 @@ def __init__( that are reserved for this function :param environment: Environment variables that are accessible from function code during execution + :param logging_config: The function's Amazon CloudWatch Logs settings """ self.app_module, self.app_name = app.rsplit(".", 1) @@ -104,6 +107,7 @@ def __init__( logs_retention_in_days=logs_retention_in_days, reserved_concurrent_executions=reserved_concurrent_executions, environment=environment, + logging_config=logging_config, ) def populate_package_dir(self, package_dir: str) -> None: @@ -138,6 +142,7 @@ def __init__( timeout: int = 3, memory_size: int | None = None, logs_retention_in_days: int | None = None, + logging_config: LoggingConfig | None = None, ): """Initialize a Flask AWS lambda function using Python 3.8 runtime. @@ -155,4 +160,5 @@ def __init__( timeout=timeout, memory_size=memory_size, logs_retention_in_days=logs_retention_in_days, + logging_config=logging_config, ) diff --git a/tests/tests_e3_aws/troposphere/awslambda/awslambda_test.py b/tests/tests_e3_aws/troposphere/awslambda/awslambda_test.py index 00d5627..e18ff2c 100644 --- a/tests/tests_e3_aws/troposphere/awslambda/awslambda_test.py +++ b/tests/tests_e3_aws/troposphere/awslambda/awslambda_test.py @@ -14,6 +14,7 @@ ProvisionedConcurrencyConfiguration, AliasRoutingConfiguration, VersionWeight, + LoggingConfig, ) from e3.aws import AWSEnv @@ -110,6 +111,11 @@ "Environment": { "Variables": {"env_key_1": "env_value_1", "env_key_2": "env_value2"} }, + "LoggingConfig": { + "ApplicationLogLevel": "INFO", + "LogFormat": "JSON", + "SystemLogLevel": "WARN", + }, }, "Type": "AWS::Lambda::Function", }, @@ -397,6 +403,11 @@ def test_pyfunction(stack: Stack) -> None: logs_retention_in_days=7, reserved_concurrent_executions=1, environment={"env_key_1": "env_value_1", "env_key_2": "env_value2"}, + logging_config=LoggingConfig( + ApplicationLogLevel="INFO", + LogFormat="JSON", + SystemLogLevel="WARN", + ), ) ) print(stack.export()["Resources"])