From b6bcda4f0461b0d17afcb8b9dc3f28e2e183ef14 Mon Sep 17 00:00:00 2001 From: Sashwatdas123 Date: Mon, 25 May 2026 15:07:38 +0530 Subject: [PATCH 1/3] feat: add support for NEW_RELIC_APP_NAME environment variable --- newrelic_lambda_cli/cli/layers.py | 9 +++++++++ newrelic_lambda_cli/layers.py | 5 +++++ newrelic_lambda_cli/types.py | 1 + 3 files changed, 15 insertions(+) diff --git a/newrelic_lambda_cli/cli/layers.py b/newrelic_lambda_cli/cli/layers.py index 2ceb782..1d24f3a 100644 --- a/newrelic_lambda_cli/cli/layers.py +++ b/newrelic_lambda_cli/cli/layers.py @@ -183,6 +183,15 @@ def register(group): "log output in CloudWatch, reducing CloudWatch log volume without affecting " "telemetry delivery to New Relic", ) +@click.option( + "--app-name", + "app_name", + help="Set the NEW_RELIC_APP_NAME environment variable on instrumented functions. " + "If a different value is passed during an upgrade (--upgrade), the existing " + "NEW_RELIC_APP_NAME will be updated to the new value.", + metavar="", + default=None, +) @click.pass_context def install(ctx, **kwargs): """Install New Relic AWS Lambda Layers""" diff --git a/newrelic_lambda_cli/layers.py b/newrelic_lambda_cli/layers.py index f6c029b..d50e140 100644 --- a/newrelic_lambda_cli/layers.py +++ b/newrelic_lambda_cli/layers.py @@ -18,6 +18,7 @@ NEW_RELIC_ENV_VARS = ( "NEW_RELIC_ACCOUNT_ID", + "NEW_RELIC_APP_NAME", "NEW_RELIC_EXTENSION_LOGS_ENABLED", "NEW_RELIC_EXTENSION_SEND_EXTENSION_LOGS", "NEW_RELIC_EXTENSION_SEND_FUNCTION_LOGS", @@ -222,6 +223,10 @@ def _add_new_relic(input, config, nr_license_key): input.nr_account_id ) + if input.app_name: + update_kwargs["Environment"]["Variables"]["NEW_RELIC_APP_NAME"] = str(input.app_name) + success("Successfully set NEW_RELIC_APP_NAME to '%s' for the function" % input.app_name) + # Update the NEW_RELIC_LAMBDA_HANDLER envvars only when it's a new install. if runtime_handler and handler != runtime_handler: if "nodejs" in runtime: diff --git a/newrelic_lambda_cli/types.py b/newrelic_lambda_cli/types.py index f83445a..4be8f55 100644 --- a/newrelic_lambda_cli/types.py +++ b/newrelic_lambda_cli/types.py @@ -121,6 +121,7 @@ "esm", "slim", "extension_logs_enabled", + "app_name", ] LAYER_UNINSTALL_KEYS = [ From ec62410acdcec8086e7e6d044ae8a650956b98d9 Mon Sep 17 00:00:00 2001 From: Sashwatdas123 Date: Mon, 25 May 2026 15:27:37 +0530 Subject: [PATCH 2/3] feat: add support for --app-name flag in layers install and related tests --- newrelic_lambda_cli/layers.py | 9 +++- tests/cli/test_layers.py | 36 ++++++++++++++ tests/test_layers.py | 90 +++++++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+), 2 deletions(-) diff --git a/newrelic_lambda_cli/layers.py b/newrelic_lambda_cli/layers.py index d50e140..ad8e9c5 100644 --- a/newrelic_lambda_cli/layers.py +++ b/newrelic_lambda_cli/layers.py @@ -224,8 +224,13 @@ def _add_new_relic(input, config, nr_license_key): ) if input.app_name: - update_kwargs["Environment"]["Variables"]["NEW_RELIC_APP_NAME"] = str(input.app_name) - success("Successfully set NEW_RELIC_APP_NAME to '%s' for the function" % input.app_name) + update_kwargs["Environment"]["Variables"]["NEW_RELIC_APP_NAME"] = str( + input.app_name + ) + success( + "Successfully set NEW_RELIC_APP_NAME to '%s' for the function" + % input.app_name + ) # Update the NEW_RELIC_LAMBDA_HANDLER envvars only when it's a new install. if runtime_handler and handler != runtime_handler: diff --git a/tests/cli/test_layers.py b/tests/cli/test_layers.py index 5b32b71..78afe69 100644 --- a/tests/cli/test_layers.py +++ b/tests/cli/test_layers.py @@ -65,6 +65,42 @@ def test_layers_install(aws_credentials, cli_runner): assert "Could not find function: foobar" in result2.stderr +@mock_aws +def test_layers_install_app_name_flag(aws_credentials, cli_runner): + """ + Assert that 'newrelic-lambda layers install --app-name' accepts the flag + and passes it through without raising an unrecognized option error + """ + register_groups(cli) + + result = cli_runner.invoke( + cli, + [ + "layers", + "install", + "--no-aws-permissions-check", + "--function", + "foobar", + "--nr-account-id", + "12345678", + "--aws-region", + "us-east-1", + "--app-name", + "my-custom-app", + ], + env={ + "AWS_ACCESS_KEY_ID": "testing", + "AWS_SECRET_ACCESS_KEY": "testing", + "AWS_SECURITY_TOKEN": "testing", + "AWS_SESSION_TOKEN": "testing", + }, + ) + + assert "no such option" not in result.output + assert result.exit_code == 1 + assert "Could not find function: foobar" in result.stderr + + @mock_aws def test_layers_uninstall(aws_credentials, cli_runner): """ diff --git a/tests/test_layers.py b/tests/test_layers.py index 8ec99b5..ea82734 100644 --- a/tests/test_layers.py +++ b/tests/test_layers.py @@ -1809,3 +1809,93 @@ def test_extension_logs_removed_on_uninstall(aws_credentials, mock_function_conf "NEW_RELIC_EXTENSION_LOGS_ENABLED" not in update_kwargs["Environment"]["Variables"] ) + + +@mock_aws +def test_sets_app_name_from_flag(aws_credentials, mock_function_config): + """Sets NEW_RELIC_APP_NAME when --app-name flag is provided""" + session = boto3.Session(region_name="us-east-1") + config = mock_function_config("python3.12") + + update_kwargs = _add_new_relic( + layer_install( + session=session, + aws_region="us-east-1", + nr_account_id=12345, + enable_extension=True, + app_name="my-custom-app", + ), + config, + nr_license_key=None, + ) + + assert ( + update_kwargs["Environment"]["Variables"]["NEW_RELIC_APP_NAME"] + == "my-custom-app" + ) + + +@mock_aws +def test_app_name_flag_overrides_existing_value(aws_credentials, mock_function_config): + """--app-name flag overrides existing NEW_RELIC_APP_NAME already set on the function""" + session = boto3.Session(region_name="us-east-1") + config = mock_function_config("python3.12") + config["Configuration"]["Environment"]["Variables"][ + "NEW_RELIC_APP_NAME" + ] = "existing-app" + + update_kwargs = _add_new_relic( + layer_install( + session=session, + aws_region="us-east-1", + nr_account_id=12345, + enable_extension=True, + app_name="new-app-name", + upgrade=True, + ), + config, + nr_license_key=None, + ) + + assert ( + update_kwargs["Environment"]["Variables"]["NEW_RELIC_APP_NAME"] + == "new-app-name" + ) + + +@mock_aws +def test_app_name_not_set_when_flag_omitted(aws_credentials, mock_function_config): + """NEW_RELIC_APP_NAME is not set when --app-name flag is not provided""" + session = boto3.Session(region_name="us-east-1") + config = mock_function_config("python3.12") + + update_kwargs = _add_new_relic( + layer_install( + session=session, + aws_region="us-east-1", + nr_account_id=12345, + enable_extension=True, + ), + config, + nr_license_key=None, + ) + + assert "NEW_RELIC_APP_NAME" not in update_kwargs["Environment"]["Variables"] + + +@mock_aws +def test_app_name_removed_on_uninstall(aws_credentials, mock_function_config): + """NEW_RELIC_APP_NAME is removed during uninstall""" + session = boto3.Session(region_name="us-east-1") + config = mock_function_config("python3.12") + config["Configuration"]["Handler"] = "newrelic_lambda_wrapper.handler" + config["Configuration"]["Environment"]["Variables"][ + "NEW_RELIC_LAMBDA_HANDLER" + ] = "original_handler" + config["Configuration"]["Environment"]["Variables"]["NEW_RELIC_APP_NAME"] = "my-app" + + update_kwargs = _remove_new_relic( + layer_uninstall(session=session, aws_region="us-east-1"), config + ) + + assert "NEW_RELIC_APP_NAME" not in update_kwargs["Environment"]["Variables"] From 487e3a0b004be3e8bffccd89432d38d05b4567cd Mon Sep 17 00:00:00 2001 From: Sashwatdas123 Date: Mon, 25 May 2026 15:56:55 +0530 Subject: [PATCH 3/3] feat: add --app-name flag support in layers install and related tests --- README.md | 1 + tests/cli/test_layers.py | 10 ++++++++++ tests/test_layers.py | 29 +++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/README.md b/README.md index e172fd7..8b5ccba 100644 --- a/README.md +++ b/README.md @@ -195,6 +195,7 @@ newrelic-lambda layers install \ | `--esm` | No | For Node.js functions using ES Modules (ESM), enable the specific ESM wrapper during installation (e.g., using the --esm flag). This sets the Lambda handler to `/opt/nodejs/node_modules/newrelic-esm-lambda-wrapper/index.handler`. | | `--extension-logs-enabled` | No | Set `NEW_RELIC_EXTENSION_LOGS_ENABLED=true` to enable `[NR_EXT]` extension log output in CloudWatch. This is the default extension behaviour.| | `--extension-logs-disabled` | No | Set `NEW_RELIC_EXTENSION_LOGS_ENABLED=false` to suppress `[NR_EXT]` extension log output in CloudWatch. | +| `--app-name` | No | Set the `NEW_RELIC_APP_NAME` environment variable on instrumented functions. If a different value is passed during an upgrade (`--upgrade`), the existing `NEW_RELIC_APP_NAME` will be updated to the new value. | #### Uninstall Layer diff --git a/tests/cli/test_layers.py b/tests/cli/test_layers.py index 78afe69..b1e8810 100644 --- a/tests/cli/test_layers.py +++ b/tests/cli/test_layers.py @@ -1,8 +1,18 @@ +import pytest +from click.testing import CliRunner from moto import mock_aws from newrelic_lambda_cli.cli import cli, register_groups +@pytest.fixture(scope="module") +def cli_runner(): + try: + return CliRunner(mix_stderr=False) + except TypeError: + return CliRunner() + + @mock_aws def test_layers_install(aws_credentials, cli_runner): """ diff --git a/tests/test_layers.py b/tests/test_layers.py index ea82734..177c2fc 100644 --- a/tests/test_layers.py +++ b/tests/test_layers.py @@ -1883,6 +1883,35 @@ def test_app_name_not_set_when_flag_omitted(aws_credentials, mock_function_confi assert "NEW_RELIC_APP_NAME" not in update_kwargs["Environment"]["Variables"] +@mock_aws +def test_existing_app_name_preserved_when_flag_omitted_on_upgrade( + aws_credentials, mock_function_config +): + """Existing NEW_RELIC_APP_NAME is preserved when --app-name is not passed during upgrade""" + session = boto3.Session(region_name="us-east-1") + config = mock_function_config("python3.12") + config["Configuration"]["Environment"]["Variables"][ + "NEW_RELIC_APP_NAME" + ] = "previously-set-app" + + update_kwargs = _add_new_relic( + layer_install( + session=session, + aws_region="us-east-1", + nr_account_id=12345, + enable_extension=True, + upgrade=True, + ), + config, + nr_license_key=None, + ) + + assert ( + update_kwargs["Environment"]["Variables"]["NEW_RELIC_APP_NAME"] + == "previously-set-app" + ) + + @mock_aws def test_app_name_removed_on_uninstall(aws_credentials, mock_function_config): """NEW_RELIC_APP_NAME is removed during uninstall"""