Skip to content

Commit

Permalink
Sam local Invoke support for Advanced logging (aws#552)
Browse files Browse the repository at this point in the history
* Sam local support for Advanced logging

* Sam local support for Advanced logging

* pass AWS_LAMBDA_LOG_FORMAT to runtime

* remove unnecessary if statement
  • Loading branch information
jonife authored Nov 15, 2023
1 parent c2fd98d commit c54eca7
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 0 deletions.
1 change: 1 addition & 0 deletions samcli/commands/local/lib/local_lambda.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ def _make_env_vars(self, function: Function) -> EnvironmentVariables:
function.memory,
function.timeout,
function.handler,
function.logging_config,
variables=variables,
shell_env_values=shell_env,
override_values=overrides,
Expand Down
2 changes: 2 additions & 0 deletions samcli/lib/providers/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ class Function(NamedTuple):
stack_path: str = ""
# Configuration for runtime management. Includes the fields `UpdateRuntimeOn` and `RuntimeVersionArn` (optional).
runtime_management_config: Optional[Dict] = None
# LoggingConfig for Advanced logging
logging_config: Optional[Dict] = None

@property
def full_path(self) -> str:
Expand Down
1 change: 1 addition & 0 deletions samcli/lib/providers/sam_function_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,7 @@ def _build_function_configuration(
function_url_config=resource_properties.get("FunctionUrlConfig"),
runtime_management_config=resource_properties.get("RuntimeManagementConfig"),
function_build_info=function_build_info,
logging_config=resource_properties.get("LoggingConfig"),
)

@staticmethod
Expand Down
14 changes: 14 additions & 0 deletions samcli/local/lambdafn/env_vars.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def __init__(
function_memory=None,
function_timeout=None,
function_handler=None,
function_logging_config=None,
variables=None,
shell_env_values=None,
override_values=None,
Expand All @@ -58,6 +59,7 @@ def __init__(
:param integer function_memory: Memory size of the function in megabytes
:param integer function_timeout: Function's timeout in seconds
:param string function_handler: Handler of the function
:param string function_logging_config: Logging Config for the function
:param dict variables: Optional. Dict whose key is the environment variable names and value is the default
values for the variable.
:param dict shell_env_values: Optional. Dict containing values for the variables grabbed from the shell's
Expand All @@ -79,6 +81,7 @@ def __init__(
self.shell_env_values = shell_env_values or {}
self.override_values = override_values or {}
self.aws_creds = aws_creds or {}
self.logging_config = function_logging_config or {}

def resolve(self):
"""
Expand Down Expand Up @@ -179,6 +182,17 @@ def _get_aws_variables(self):
if self.aws_creds.get("sessiontoken"):
result["AWS_SESSION_TOKEN"] = self.aws_creds.get("sessiontoken")

# Add the ApplicationLogLevel as a env variable and also update the function's LogGroup name
log_group = self.logging_config.get("LogGroup")
if log_group:
result["AWS_LAMBDA_LOG_GROUP_NAME"] = log_group

log_format = self.logging_config.get("LogFormat")
if log_format:
result["AWS_LAMBDA_LOG_FORMAT"] = log_format
if log_format == "JSON":
result["AWS_LAMBDA_LOG_LEVEL"] = self.logging_config.get("ApplicationLogLevel", "INFO")

return result

def _stringify_value(self, value):
Expand Down
3 changes: 3 additions & 0 deletions tests/unit/commands/local/lib/test_local_lambda.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ def test_must_work_with_override_values(
function_url_config=None,
runtime_management_config=None,
function_build_info=FunctionBuildInfo.BuildableZip,
logging_config={"LogFormat": "JSON"},
)

self.local_lambda.env_vars_values = env_vars_values
Expand All @@ -264,6 +265,7 @@ def test_must_work_with_override_values(
function.memory,
function.timeout,
function.handler,
function.logging_config,
variables={"var1": "value1"},
shell_env_values=os_environ,
override_values=expected_override_value,
Expand Down Expand Up @@ -362,6 +364,7 @@ def test_must_work_with_invalid_environment_variable(self, environment_variable,
function.memory,
function.timeout,
function.handler,
None,
variables=None,
shell_env_values=os_environ,
override_values={},
Expand Down
98 changes: 98 additions & 0 deletions tests/unit/local/lambdafn/test_env_vars.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@ def test_must_initialize_with_empty_values(self):
memory = 123
timeout = 10
handler = "handler"
logging_config = {"logFormat": "JSON"}

environ = EnvironmentVariables()
environ.memory = memory
environ.timeout = timeout
environ.handler = handler
environ.logging_config = logging_config

self.assertEqual(environ.memory, memory)
self.assertEqual(environ.timeout, timeout)
self.assertEqual(environ.handler, handler)
self.assertEqual(environ.logging_config, logging_config)

def test_must_initialize_values_with_required_values(self):
memory = 123
Expand Down Expand Up @@ -332,6 +335,101 @@ def test_must_work_with_partial_aws_creds(self):
environ = EnvironmentVariables(self.name, self.memory, self.timeout, self.handler, aws_creds=creds)
self.assertEqual(expected, environ._get_aws_variables())

def test_must_work_with_text_logformat(self):
expected = {
"AWS_SAM_LOCAL": "true",
"AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "1024",
"AWS_LAMBDA_FUNCTION_TIMEOUT": "123",
"AWS_LAMBDA_FUNCTION_HANDLER": "handler",
"AWS_LAMBDA_FUNCTION_NAME": self.name,
"AWS_LAMBDA_FUNCTION_VERSION": "$LATEST",
"AWS_LAMBDA_LOG_GROUP_NAME": f"aws/lambda/{self.name}",
"AWS_LAMBDA_LOG_STREAM_NAME": "$LATEST",
"AWS_ACCOUNT_ID": "123456789012",
# Default values assigned to these variables
"AWS_REGION": "us-east-1",
"AWS_DEFAULT_REGION": "us-east-1",
"AWS_ACCESS_KEY_ID": "defaultkey",
"AWS_SECRET_ACCESS_KEY": "defaultsecret",
"AWS_LAMBDA_LOG_FORMAT": "Text",
}

logging_config = {"LogFormat": "Text"}
environ = EnvironmentVariables(self.name, self.memory, self.timeout, self.handler, logging_config)
self.assertEqual(expected, environ._get_aws_variables())

def test_must_work_with_default_json_logging_config(self):
expected = {
"AWS_SAM_LOCAL": "true",
"AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "1024",
"AWS_LAMBDA_FUNCTION_TIMEOUT": "123",
"AWS_LAMBDA_FUNCTION_HANDLER": "handler",
"AWS_LAMBDA_FUNCTION_NAME": self.name,
"AWS_LAMBDA_FUNCTION_VERSION": "$LATEST",
"AWS_LAMBDA_LOG_GROUP_NAME": f"aws/lambda/{self.name}",
"AWS_LAMBDA_LOG_STREAM_NAME": "$LATEST",
"AWS_ACCOUNT_ID": "123456789012",
# Default values assigned to these variables
"AWS_REGION": "us-east-1",
"AWS_DEFAULT_REGION": "us-east-1",
"AWS_ACCESS_KEY_ID": "defaultkey",
"AWS_SECRET_ACCESS_KEY": "defaultsecret",
"AWS_LAMBDA_LOG_LEVEL": "INFO",
"AWS_LAMBDA_LOG_FORMAT": "JSON",
}

logging_config = {"LogFormat": "JSON"}
environ = EnvironmentVariables(self.name, self.memory, self.timeout, self.handler, logging_config)
self.assertEqual(expected, environ._get_aws_variables())

def test_must_work_with_set_application_log_level(self):
expected = {
"AWS_SAM_LOCAL": "true",
"AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "1024",
"AWS_LAMBDA_FUNCTION_TIMEOUT": "123",
"AWS_LAMBDA_FUNCTION_HANDLER": "handler",
"AWS_LAMBDA_FUNCTION_NAME": self.name,
"AWS_LAMBDA_FUNCTION_VERSION": "$LATEST",
"AWS_LAMBDA_LOG_GROUP_NAME": f"aws/lambda/{self.name}",
"AWS_LAMBDA_LOG_STREAM_NAME": "$LATEST",
"AWS_ACCOUNT_ID": "123456789012",
# Default values assigned to these variables
"AWS_REGION": "us-east-1",
"AWS_DEFAULT_REGION": "us-east-1",
"AWS_ACCESS_KEY_ID": "defaultkey",
"AWS_SECRET_ACCESS_KEY": "defaultsecret",
"AWS_LAMBDA_LOG_LEVEL": "TRACE",
"AWS_LAMBDA_LOG_FORMAT": "JSON",
}

logging_config = {"LogFormat": "JSON", "ApplicationLogLevel": "TRACE"}
environ = EnvironmentVariables(self.name, self.memory, self.timeout, self.handler, logging_config)
self.assertEqual(expected, environ._get_aws_variables())

def test_must_work_with_custom_log_group_name(self):
expected = {
"AWS_SAM_LOCAL": "true",
"AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "1024",
"AWS_LAMBDA_FUNCTION_TIMEOUT": "123",
"AWS_LAMBDA_FUNCTION_HANDLER": "handler",
"AWS_LAMBDA_FUNCTION_NAME": self.name,
"AWS_LAMBDA_FUNCTION_VERSION": "$LATEST",
"AWS_LAMBDA_LOG_GROUP_NAME": "myCustomLogGroup",
"AWS_LAMBDA_LOG_STREAM_NAME": "$LATEST",
"AWS_ACCOUNT_ID": "123456789012",
# Default values assigned to these variables
"AWS_REGION": "us-east-1",
"AWS_DEFAULT_REGION": "us-east-1",
"AWS_ACCESS_KEY_ID": "defaultkey",
"AWS_SECRET_ACCESS_KEY": "defaultsecret",
"AWS_LAMBDA_LOG_LEVEL": "TRACE",
"AWS_LAMBDA_LOG_FORMAT": "JSON",
}

logging_config = {"LogFormat": "JSON", "ApplicationLogLevel": "TRACE", "LogGroup": "myCustomLogGroup"}
environ = EnvironmentVariables(self.name, self.memory, self.timeout, self.handler, logging_config)
self.assertEqual(expected, environ._get_aws_variables())


class TestEnvironmentVariables_stringify_value(TestCase):
def setUp(self):
Expand Down

0 comments on commit c54eca7

Please sign in to comment.