From 39fe8cda5b41846cbdcbc4fa57155377e4adbc0c Mon Sep 17 00:00:00 2001 From: Mehmet Nuri Deveci <5735811+mndeveci@users.noreply.github.com> Date: Tue, 2 Jan 2024 13:41:31 -0800 Subject: [PATCH] fix: getting logging information from lambda (#6477) * fix: getting logging information from lambda * update formatting * add unit tests * add integration tests * bump python versions that is used in the test templates --- requirements/base.txt | 2 +- .../cw_logs/cw_log_group_provider.py | 4 +++- tests/integration/logs/test_logs_command.py | 1 + .../function-with-custom-logging/app.py | 5 +++++ .../function-with-custom-logging/app.py | 5 +++++ .../child-stack/grand-child-stack/template.yaml | 15 +++++++++++++-- .../child-stack/template.yaml | 15 +++++++++++++-- .../function-with-custom-logging/app.py | 5 +++++ .../logs/nested-python-apigw-sfn/template.yaml | 15 +++++++++++++-- .../function-with-custom-logging/app.py | 5 +++++ .../testdata/logs/python-apigw-sfn/template.yaml | 15 +++++++++++++-- .../cw_logs/test_cw_log_group_provider.py | 5 ++++- 12 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 tests/integration/testdata/logs/nested-python-apigw-sfn/child-stack/function-with-custom-logging/app.py create mode 100644 tests/integration/testdata/logs/nested-python-apigw-sfn/child-stack/grand-child-stack/function-with-custom-logging/app.py create mode 100644 tests/integration/testdata/logs/nested-python-apigw-sfn/function-with-custom-logging/app.py create mode 100644 tests/integration/testdata/logs/python-apigw-sfn/function-with-custom-logging/app.py diff --git a/requirements/base.txt b/requirements/base.txt index 72d746c2c9..f91f8d83eb 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -1,7 +1,7 @@ chevron~=0.12 click~=8.1 Flask<3.1 -boto3>=1.26.109,<2 +boto3>=1.29.2,<2 jmespath~=1.0.1 ruamel_yaml~=0.18.5 PyYAML~=6.0,>=6.0.1 diff --git a/samcli/lib/observability/cw_logs/cw_log_group_provider.py b/samcli/lib/observability/cw_logs/cw_log_group_provider.py index 0ff83925e5..e920ee41a7 100644 --- a/samcli/lib/observability/cw_logs/cw_log_group_provider.py +++ b/samcli/lib/observability/cw_logs/cw_log_group_provider.py @@ -53,7 +53,9 @@ def for_lambda_function(boto_client_provider: BotoProviderType, function_name: s """ log_group_name = "" try: - function_configuration = boto_client_provider("lambda").get_function_configuration(function_name) + function_configuration = boto_client_provider("lambda").get_function_configuration( + FunctionName=function_name + ) logging_config = function_configuration.get("LoggingConfig") if logging_config: log_group_name = logging_config.get("LogGroup") diff --git a/tests/integration/logs/test_logs_command.py b/tests/integration/logs/test_logs_command.py index 22a15b8c72..f1edd48a23 100644 --- a/tests/integration/logs/test_logs_command.py +++ b/tests/integration/logs/test_logs_command.py @@ -230,6 +230,7 @@ def _check_logs(self, cmd_list: List, log_strings: List[str], output: str = "tex REGULAR_STACK_FUNCTION_LIST = [ "ApiGwFunction", "SfnFunction", + "FunctionWithCustomLoggingConfig", ] REGULAR_STACK_APIGW_LIST = [ "HelloWorldServerlessApi", diff --git a/tests/integration/testdata/logs/nested-python-apigw-sfn/child-stack/function-with-custom-logging/app.py b/tests/integration/testdata/logs/nested-python-apigw-sfn/child-stack/function-with-custom-logging/app.py new file mode 100644 index 0000000000..989804c801 --- /dev/null +++ b/tests/integration/testdata/logs/nested-python-apigw-sfn/child-stack/function-with-custom-logging/app.py @@ -0,0 +1,5 @@ + +def handler(event, context): + print("Hello world from ChildStack/FunctionWithCustomLoggingConfig function") + print("this should be filtered ChildStackFunctionWithCustomLoggingConfig") + return {} \ No newline at end of file diff --git a/tests/integration/testdata/logs/nested-python-apigw-sfn/child-stack/grand-child-stack/function-with-custom-logging/app.py b/tests/integration/testdata/logs/nested-python-apigw-sfn/child-stack/grand-child-stack/function-with-custom-logging/app.py new file mode 100644 index 0000000000..7cd5b2269f --- /dev/null +++ b/tests/integration/testdata/logs/nested-python-apigw-sfn/child-stack/grand-child-stack/function-with-custom-logging/app.py @@ -0,0 +1,5 @@ + +def handler(event, context): + print("Hello world from ChildStack/GrandChildStack/FunctionWithCustomLoggingConfig function") + print("this should be filtered ChildStackGrandChildStackFunctionWithCustomLoggingConfig") + return {} diff --git a/tests/integration/testdata/logs/nested-python-apigw-sfn/child-stack/grand-child-stack/template.yaml b/tests/integration/testdata/logs/nested-python-apigw-sfn/child-stack/grand-child-stack/template.yaml index b7a4dc30f0..6c95dbce72 100644 --- a/tests/integration/testdata/logs/nested-python-apigw-sfn/child-stack/grand-child-stack/template.yaml +++ b/tests/integration/testdata/logs/nested-python-apigw-sfn/child-stack/grand-child-stack/template.yaml @@ -66,7 +66,7 @@ Resources: Properties: CodeUri: apigw-function/ Handler: app.handler - Runtime: python3.9 + Runtime: python3.12 Tracing: Active Events: HelloWorld: @@ -81,7 +81,7 @@ Resources: Properties: CodeUri: sfn-function/ Handler: app.handler - Runtime: python3.9 + Runtime: python3.12 Tracing: Active HelloWorldServerlessApi: @@ -113,6 +113,17 @@ Resources: ManagedPolicyArns: - !Sub "arn:${AWS::Partition}:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs" + FunctionWithCustomLoggingConfig: + Type: AWS::Serverless::Function + Properties: + CodeUri: function-with-custom-logging/ + Handler: app.handler + Runtime: python3.12 + Tracing: Active + LoggingConfig: + LogFormat: JSON + LogGroup: !Sub /aws/lambda/${AWS::StackName} + Outputs: HelloWorldServerlessApi: Description: "API Gateway endpoint URL for Prod stage for Hello World function" diff --git a/tests/integration/testdata/logs/nested-python-apigw-sfn/child-stack/template.yaml b/tests/integration/testdata/logs/nested-python-apigw-sfn/child-stack/template.yaml index c6f1aef18f..83ed191545 100644 --- a/tests/integration/testdata/logs/nested-python-apigw-sfn/child-stack/template.yaml +++ b/tests/integration/testdata/logs/nested-python-apigw-sfn/child-stack/template.yaml @@ -66,7 +66,7 @@ Resources: Properties: CodeUri: apigw-function/ Handler: app.handler - Runtime: python3.9 + Runtime: python3.12 Tracing: Active Events: HelloWorld: @@ -81,7 +81,7 @@ Resources: Properties: CodeUri: sfn-function/ Handler: app.handler - Runtime: python3.9 + Runtime: python3.12 Tracing: Active HelloWorldServerlessApi: @@ -113,6 +113,17 @@ Resources: ManagedPolicyArns: - !Sub "arn:${AWS::Partition}:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs" + FunctionWithCustomLoggingConfig: + Type: AWS::Serverless::Function + Properties: + CodeUri: function-with-custom-logging/ + Handler: app.handler + Runtime: python3.12 + Tracing: Active + LoggingConfig: + LogFormat: JSON + LogGroup: !Sub /aws/lambda/${AWS::StackName} + GrandChildStack: Type: AWS::Serverless::Application Properties: diff --git a/tests/integration/testdata/logs/nested-python-apigw-sfn/function-with-custom-logging/app.py b/tests/integration/testdata/logs/nested-python-apigw-sfn/function-with-custom-logging/app.py new file mode 100644 index 0000000000..e980e304ad --- /dev/null +++ b/tests/integration/testdata/logs/nested-python-apigw-sfn/function-with-custom-logging/app.py @@ -0,0 +1,5 @@ + +def handler(event, context): + print("Hello world from FunctionWithCustomLoggingConfig function") + print("this should be filtered FunctionWithCustomLoggingConfig") + return {} diff --git a/tests/integration/testdata/logs/nested-python-apigw-sfn/template.yaml b/tests/integration/testdata/logs/nested-python-apigw-sfn/template.yaml index 5506f108f3..02fb86362c 100644 --- a/tests/integration/testdata/logs/nested-python-apigw-sfn/template.yaml +++ b/tests/integration/testdata/logs/nested-python-apigw-sfn/template.yaml @@ -66,7 +66,7 @@ Resources: Properties: CodeUri: apigw-function/ Handler: app.handler - Runtime: python3.9 + Runtime: python3.12 Tracing: Active Events: HelloWorld: @@ -81,7 +81,7 @@ Resources: Properties: CodeUri: sfn-function/ Handler: app.handler - Runtime: python3.9 + Runtime: python3.12 Tracing: Active HelloWorldServerlessApi: @@ -113,6 +113,17 @@ Resources: ManagedPolicyArns: - !Sub "arn:${AWS::Partition}:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs" + FunctionWithCustomLoggingConfig: + Type: AWS::Serverless::Function + Properties: + CodeUri: function-with-custom-logging/ + Handler: app.handler + Runtime: python3.12 + Tracing: Active + LoggingConfig: + LogFormat: JSON + LogGroup: !Sub /aws/lambda/${AWS::StackName} + ChildStack: Type: AWS::Serverless::Application Properties: diff --git a/tests/integration/testdata/logs/python-apigw-sfn/function-with-custom-logging/app.py b/tests/integration/testdata/logs/python-apigw-sfn/function-with-custom-logging/app.py new file mode 100644 index 0000000000..e980e304ad --- /dev/null +++ b/tests/integration/testdata/logs/python-apigw-sfn/function-with-custom-logging/app.py @@ -0,0 +1,5 @@ + +def handler(event, context): + print("Hello world from FunctionWithCustomLoggingConfig function") + print("this should be filtered FunctionWithCustomLoggingConfig") + return {} diff --git a/tests/integration/testdata/logs/python-apigw-sfn/template.yaml b/tests/integration/testdata/logs/python-apigw-sfn/template.yaml index b7a4dc30f0..6c95dbce72 100644 --- a/tests/integration/testdata/logs/python-apigw-sfn/template.yaml +++ b/tests/integration/testdata/logs/python-apigw-sfn/template.yaml @@ -66,7 +66,7 @@ Resources: Properties: CodeUri: apigw-function/ Handler: app.handler - Runtime: python3.9 + Runtime: python3.12 Tracing: Active Events: HelloWorld: @@ -81,7 +81,7 @@ Resources: Properties: CodeUri: sfn-function/ Handler: app.handler - Runtime: python3.9 + Runtime: python3.12 Tracing: Active HelloWorldServerlessApi: @@ -113,6 +113,17 @@ Resources: ManagedPolicyArns: - !Sub "arn:${AWS::Partition}:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs" + FunctionWithCustomLoggingConfig: + Type: AWS::Serverless::Function + Properties: + CodeUri: function-with-custom-logging/ + Handler: app.handler + Runtime: python3.12 + Tracing: Active + LoggingConfig: + LogFormat: JSON + LogGroup: !Sub /aws/lambda/${AWS::StackName} + Outputs: HelloWorldServerlessApi: Description: "API Gateway endpoint URL for Prod stage for Hello World function" diff --git a/tests/unit/lib/observability/cw_logs/test_cw_log_group_provider.py b/tests/unit/lib/observability/cw_logs/test_cw_log_group_provider.py index ac7cd0843c..23a753ed19 100644 --- a/tests/unit/lib/observability/cw_logs/test_cw_log_group_provider.py +++ b/tests/unit/lib/observability/cw_logs/test_cw_log_group_provider.py @@ -1,5 +1,5 @@ from unittest import TestCase -from unittest.mock import Mock, ANY +from unittest.mock import Mock, ANY, call from parameterized import parameterized @@ -26,6 +26,9 @@ def test_must_return_custom_log_group_name(self): result = LogGroupProvider.for_lambda_function(given_client_provider, "my_function_name") self.assertEqual(expected, result) + given_client_provider.assert_has_calls( + [call("lambda").get_function_configuration(FunctionName="my_function_name")] + ) def test_must_return_default_log_group_name_with_exception_raised(self): expected = "/aws/lambda/my_function_name"