diff --git a/ddtrace/internal/schema/processor.py b/ddtrace/internal/schema/processor.py index a2927efc6d8..8d5559ecae3 100644 --- a/ddtrace/internal/schema/processor.py +++ b/ddtrace/internal/schema/processor.py @@ -1,6 +1,5 @@ from ddtrace._trace.processor import TraceProcessor from ddtrace.constants import _BASE_SERVICE_KEY -from ddtrace.internal.serverless import in_aws_lambda from ddtrace.internal.settings._config import config from . import schematize_service_name @@ -9,12 +8,9 @@ class BaseServiceProcessor(TraceProcessor): def __init__(self): self._global_service = schematize_service_name((config.service or "").lower()) - self._in_aws_lambda = in_aws_lambda() def process_trace(self, trace): - # AWS Lambda spans receive unhelpful base_service value of runtime - # Remove base_service to prevent service overrides in Lambda spans - if not trace or self._in_aws_lambda: + if not trace: return trace traces_to_process = filter( diff --git a/ddtrace/internal/settings/_config.py b/ddtrace/internal/settings/_config.py index a94f77960da..453d0e678e7 100644 --- a/ddtrace/internal/settings/_config.py +++ b/ddtrace/internal/settings/_config.py @@ -498,6 +498,8 @@ def __init__(self) -> None: self._inferred_base_service = detect_service(sys.argv) + if self.service is None and in_aws_lambda(): + self.service = _get_config("AWS_LAMBDA_FUNCTION_NAME", DEFAULT_SPAN_SERVICE_NAME) if self.service is None and in_gcp_function(): self.service = _get_config(["K_SERVICE", "FUNCTION_NAME"], DEFAULT_SPAN_SERVICE_NAME) if self.service is None and in_azure_function(): diff --git a/releasenotes/notes/serverless-base-service-lambda-b3c9f1e2d4a58701.yaml b/releasenotes/notes/serverless-base-service-lambda-b3c9f1e2d4a58701.yaml new file mode 100644 index 00000000000..7d605044f1d --- /dev/null +++ b/releasenotes/notes/serverless-base-service-lambda-b3c9f1e2d4a58701.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + serverless: AWS Lambda functions now appear under their function name as the service + when ``DD_SERVICE`` is not explicitly configured. Service remapping rules configured + in Datadog will now apply correctly to Lambda spans. diff --git a/tests/internal/service_name/test_processor.py b/tests/internal/service_name/test_processor.py index 060aa353969..ae18122bcec 100644 --- a/tests/internal/service_name/test_processor.py +++ b/tests/internal/service_name/test_processor.py @@ -74,3 +74,20 @@ def test(processor): env=env, ) assert status == 0, (out, err) + + +@pytest.mark.subprocess( + parametrize={"DD_TRACE_SPAN_ATTRIBUTE_SCHEMA": [None, "v0", "v1"]}, + env={"AWS_LAMBDA_FUNCTION_NAME": "my-lambda-func"}, +) +def test_base_service_runs_in_lambda(): + import os + + from ddtrace.constants import _BASE_SERVICE_KEY + from ddtrace.internal.schema.processor import BaseServiceProcessor + from ddtrace.trace import Span + + processor = BaseServiceProcessor() + fake_trace = [Span("op", service="some-other-service", resource="res")] + processor.process_trace(fake_trace) + assert fake_trace[0].get_tag(_BASE_SERVICE_KEY) == os.environ["AWS_LAMBDA_FUNCTION_NAME"] diff --git a/tests/tracer/test_tracer.py b/tests/tracer/test_tracer.py index 08739274ad0..aa9eb37a44b 100644 --- a/tests/tracer/test_tracer.py +++ b/tests/tracer/test_tracer.py @@ -1018,6 +1018,20 @@ def test_detect_agentless_env_with_lambda(): ) +@pytest.mark.subprocess(env=dict(AWS_LAMBDA_FUNCTION_NAME="my-lambda-func")) +def test_service_name_defaults_to_lambda_function_name(): + import ddtrace + + assert ddtrace.config.service == "my-lambda-func" + + +@pytest.mark.subprocess(env=dict(AWS_LAMBDA_FUNCTION_NAME="my-lambda-func", DD_SERVICE="override-svc")) +def test_dd_service_takes_precedence_over_lambda_function_name(): + import ddtrace + + assert ddtrace.config.service == "override-svc" + + def test_tracer_set_runtime_tags(): with global_tracer.start_span("foobar") as span: pass