Skip to content

Commit

Permalink
fix: enable rie debug logs (#6410)
Browse files Browse the repository at this point in the history
* fix: add RIE_LOG_LEVEL_ENV_VAR to change the log level of RIE executable

* remove redundant test file

* formatting

---------

Co-authored-by: Haresh Nasit <[email protected]>
  • Loading branch information
mndeveci and hnnasit authored Dec 7, 2023
1 parent 049b801 commit 02e8b9b
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 13 deletions.
20 changes: 16 additions & 4 deletions samcli/local/docker/lambda_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Represents Lambda runtime containers.
"""
import logging
import os
from typing import List

from samcli.lib.utils.packagetype import IMAGE
Expand All @@ -12,6 +13,8 @@

LOG = logging.getLogger(__name__)

RIE_LOG_LEVEL_ENV_VAR = "SAM_CLI_RIE_DEV"


class LambdaContainer(Container):
"""
Expand All @@ -21,7 +24,6 @@ class LambdaContainer(Container):
"""

_WORKING_DIR = "/var/task"
_DEFAULT_ENTRYPOINT = ["/var/rapid/aws-lambda-rie", "--log-level", "error"]

# The Volume Mount path for debug files in docker
_DEBUGGER_VOLUME_MOUNT_PATH = "/tmp/lambci_debug_files"
Expand Down Expand Up @@ -115,10 +117,10 @@ def __init__(
_additional_entrypoint_args = (image_config.get("EntryPoint") if image_config else None) or config.get(
"Entrypoint"
)
_entrypoint = entry or self._DEFAULT_ENTRYPOINT
_entrypoint = entry or self._get_default_entry_point()
# NOTE(sriram-mv): Only add entrypoint specified in the image configuration if the entrypoint
# has not changed for debugging.
if isinstance(_additional_entrypoint_args, list) and entry == self._DEFAULT_ENTRYPOINT:
if isinstance(_additional_entrypoint_args, list) and entry == self._get_default_entry_point():
_entrypoint = _entrypoint + _additional_entrypoint_args
_work_dir = (image_config.get("WorkingDirectory") if image_config else None) or config.get("WorkingDir")

Expand All @@ -138,6 +140,16 @@ def __init__(
container_host_interface=container_host_interface,
)

@staticmethod
def _get_default_entry_point() -> List[str]:
"""
Returns default entry point for lambda container, which is the path of the RIE executable with its debugging
configuration. If SAM_CLI_RIE_DEV is set to 1, RIE log level is set to 'debug', otherwise it is kept as 'error'.
"""
#
rie_log_level = "debug" if os.environ.get(RIE_LOG_LEVEL_ENV_VAR, "0") == "1" else "error"
return ["/var/rapid/aws-lambda-rie", "--log-level", rie_log_level]

@staticmethod
def _get_exposed_ports(debug_options):
"""
Expand Down Expand Up @@ -253,7 +265,7 @@ def _get_debug_settings(runtime, debug_options=None): # pylint: disable=too-man
ie. if command is ``node index.js arg1 arg2``, then this list will be ["node", "index.js", "arg1", "arg2"]
"""

entry = LambdaContainer._DEFAULT_ENTRYPOINT
entry = LambdaContainer._get_default_entry_point()
if not debug_options:
return entry, {}

Expand Down
39 changes: 30 additions & 9 deletions tests/unit/local/docker/test_lambda_container.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
"""
Unit test for Lambda container management
"""

from unittest import TestCase
from unittest.mock import patch, Mock

from parameterized import parameterized, param

from samcli.commands.local.lib.debug_context import DebugContext
from samcli.lib.utils.packagetype import IMAGE, ZIP
from samcli.local.docker.lambda_container import LambdaContainer, Runtime
from samcli.local.docker.lambda_container import LambdaContainer, Runtime, RIE_LOG_LEVEL_ENV_VAR
from samcli.local.docker.lambda_debug_settings import DebuggingNotSupported
from samcli.local.docker.lambda_image import RAPID_IMAGE_TAG_PREFIX

Expand Down Expand Up @@ -147,7 +147,7 @@ def test_must_configure_container_properly_image_no_debug(
expected_cmd = ["mycommand"]

get_image_mock.return_value = image
get_debug_settings_mock.return_value = (LambdaContainer._DEFAULT_ENTRYPOINT, {})
get_debug_settings_mock.return_value = (LambdaContainer._get_default_entry_point(), {})
get_config_mock.return_value = {
"Cmd": ["mycommand"],
"Entrypoint": ["my-additional-entrypoint"],
Expand Down Expand Up @@ -181,7 +181,9 @@ def test_must_configure_container_properly_image_no_debug(
self.assertEqual(get_config_mock()["WorkingDir"], container._working_dir)
self.assertEqual(self.code_dir, container._host_dir)
self.assertEqual(ports, container._exposed_ports)
self.assertEqual(LambdaContainer._DEFAULT_ENTRYPOINT + get_config_mock()["Entrypoint"], container._entrypoint)
self.assertEqual(
LambdaContainer._get_default_entry_point() + get_config_mock()["Entrypoint"], container._entrypoint
)
self.assertEqual({**expected_env_vars, **{"AWS_LAMBDA_FUNCTION_HANDLER": "mycommand"}}, container._env_vars)
self.assertEqual(self.memory_mb, container._memory_limit_mb)

Expand Down Expand Up @@ -256,7 +258,7 @@ def test_must_configure_container_properly_image_debug(
self.assertEqual(ports, container._exposed_ports)
# Dis-regard Entrypoint when debug args are present.
self.assertEqual(
LambdaContainer._DEFAULT_ENTRYPOINT + self.debug_options.debug_args.split(" "), container._entrypoint
LambdaContainer._get_default_entry_point() + self.debug_options.debug_args.split(" "), container._entrypoint
)
self.assertEqual(expected_env_vars, container._env_vars)
self.assertEqual(self.memory_mb, container._memory_limit_mb)
Expand Down Expand Up @@ -331,7 +333,7 @@ def test_must_configure_container_properly_image_with_imageconfig_debug(
self.assertEqual(self.code_dir, container._host_dir)
self.assertEqual(ports, container._exposed_ports)
self.assertEqual(
LambdaContainer._DEFAULT_ENTRYPOINT + self.debug_options.debug_args.split(" "), container._entrypoint
LambdaContainer._get_default_entry_point() + self.debug_options.debug_args.split(" "), container._entrypoint
)
self.assertEqual(
{**expected_env_vars, **{"AWS_LAMBDA_FUNCTION_HANDLER": "my-imageconfig-command"}}, container._env_vars
Expand Down Expand Up @@ -382,7 +384,7 @@ def test_must_configure_container_properly_image_with_imageconfig_no_debug(
"WorkingDir": "/var/mytask",
}
get_exposed_ports_mock.return_value = ports
get_debug_settings_mock.return_value = (LambdaContainer._DEFAULT_ENTRYPOINT, {})
get_debug_settings_mock.return_value = (LambdaContainer._get_default_entry_point(), {})
get_additional_options_mock.return_value = addtl_options
get_additional_volumes_mock.return_value = addtl_volumes
expected_env_vars = {**self.env_var}
Expand Down Expand Up @@ -411,7 +413,9 @@ def test_must_configure_container_properly_image_with_imageconfig_no_debug(
self.assertEqual(self.code_dir, container._host_dir)
self.assertEqual(ports, container._exposed_ports)
self.assertEqual(
LambdaContainer._DEFAULT_ENTRYPOINT + self.image_config["EntryPoint"], container._entrypoint, "x86_64"
LambdaContainer._get_default_entry_point() + self.image_config["EntryPoint"],
container._entrypoint,
"x86_64",
)
self.assertEqual(
{**expected_env_vars, **{"AWS_LAMBDA_FUNCTION_HANDLER": "my-imageconfig-command"}}, container._env_vars
Expand Down Expand Up @@ -445,6 +449,23 @@ def test_must_fail_for_unsupported_runtime(self):

self.assertEqual(str(context.exception), "Unsupported Lambda runtime foo")

@parameterized.expand(
[
(
None,
"error",
),
(
"0",
"error",
),
("1", "debug"),
]
)
def test_rie_debug_levels(self, rie_env_var, expected_log_level):
with patch("samcli.local.docker.lambda_container.os.environ", {RIE_LOG_LEVEL_ENV_VAR: rie_env_var}):
self.assertIn(expected_log_level, LambdaContainer._get_default_entry_point())


class TestLambdaContainer_get_exposed_ports(TestCase):
def test_must_map_same_port_on_host_and_container(self):
Expand Down Expand Up @@ -508,7 +529,7 @@ def setUp(self):

def test_must_skip_if_debug_port_is_not_specified(self):
self.assertEqual(
(LambdaContainer._DEFAULT_ENTRYPOINT, {}),
(LambdaContainer._get_default_entry_point(), {}),
LambdaContainer._get_debug_settings("runtime", None),
"Must not provide entrypoint if debug port is not given",
)
Expand Down

0 comments on commit 02e8b9b

Please sign in to comment.