Skip to content

Commit a3ea6ac

Browse files
authored
Some env variables depend on DD_TRACE_ENABLED (#323)
* Some env variables depend on DD_TRACE_ENABLED * cleanup and add test cases
1 parent 3eaecde commit a3ea6ac

File tree

2 files changed

+84
-46
lines changed

2 files changed

+84
-46
lines changed

datadog_lambda/wrapper.py

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,20 @@
5757
service_env_var = os.environ.get("DD_SERVICE", "DefaultServiceName")
5858
env_env_var = os.environ.get("DD_ENV", None)
5959

60+
DD_FLUSH_TO_LOG = "DD_FLUSH_TO_LOG"
61+
DD_LOGS_INJECTION = "DD_LOGS_INJECTION"
62+
DD_MERGE_XRAY_TRACES = "DD_MERGE_XRAY_TRACES"
63+
AWS_LAMBDA_FUNCTION_NAME = "AWS_LAMBDA_FUNCTION_NAME"
64+
DD_TRACE_EXTRACTOR = "DD_TRACE_EXTRACTOR"
65+
DD_TRACE_MANAGED_SERVICES = "DD_TRACE_MANAGED_SERVICES"
66+
DD_ENCODE_AUTHORIZER_CONTEXT = "DD_ENCODE_AUTHORIZER_CONTEXT"
67+
DD_DECODE_AUTHORIZER_CONTEXT = "DD_DECODE_AUTHORIZER_CONTEXT"
68+
DD_COLD_START_TRACING = "DD_COLD_START_TRACING"
69+
DD_MIN_COLD_START_DURATION = "DD_MIN_COLD_START_DURATION"
70+
DD_COLD_START_TRACE_SKIP_LIB = "DD_COLD_START_TRACE_SKIP_LIB"
71+
DD_REQUESTS_SERVICE_NAME = "DD_REQUESTS_SERVICE_NAME"
72+
DD_SERVICE = "DD_SERVICE"
73+
6074
"""
6175
Usage:
6276
@@ -110,49 +124,52 @@ def __init__(self, func):
110124
"""Executes when the wrapped function gets wrapped"""
111125
try:
112126
self.func = func
113-
self.flush_to_log = os.environ.get("DD_FLUSH_TO_LOG", "").lower() == "true"
127+
self.flush_to_log = os.environ.get(DD_FLUSH_TO_LOG, "").lower() == "true"
114128
self.logs_injection = (
115-
os.environ.get("DD_LOGS_INJECTION", "true").lower() == "true"
129+
os.environ.get(DD_LOGS_INJECTION, "true").lower() == "true"
116130
)
117131
self.merge_xray_traces = (
118-
os.environ.get("DD_MERGE_XRAY_TRACES", "false").lower() == "true"
132+
os.environ.get(DD_MERGE_XRAY_TRACES, "false").lower() == "true"
119133
)
120-
self.function_name = os.environ.get("AWS_LAMBDA_FUNCTION_NAME", "function")
121-
self.extractor_env = os.environ.get("DD_TRACE_EXTRACTOR", None)
134+
self.function_name = os.environ.get(AWS_LAMBDA_FUNCTION_NAME, "function")
135+
self.extractor_env = os.environ.get(DD_TRACE_EXTRACTOR, None)
122136
self.trace_extractor = None
123137
self.span = None
124138
self.inferred_span = None
125-
self.make_inferred_span = (
126-
os.environ.get("DD_TRACE_MANAGED_SERVICES", "true").lower() == "true"
139+
depends_on_dd_tracing_enabled = (
140+
lambda original_boolean: dd_tracing_enabled and original_boolean
141+
)
142+
self.make_inferred_span = depends_on_dd_tracing_enabled(
143+
os.environ.get(DD_TRACE_MANAGED_SERVICES, "true").lower() == "true"
127144
)
128-
self.encode_authorizer_context = (
129-
os.environ.get("DD_ENCODE_AUTHORIZER_CONTEXT", "true").lower() == "true"
145+
self.encode_authorizer_context = depends_on_dd_tracing_enabled(
146+
os.environ.get(DD_ENCODE_AUTHORIZER_CONTEXT, "true").lower() == "true"
130147
)
131-
self.decode_authorizer_context = (
132-
os.environ.get("DD_DECODE_AUTHORIZER_CONTEXT", "true").lower() == "true"
148+
self.decode_authorizer_context = depends_on_dd_tracing_enabled(
149+
os.environ.get(DD_DECODE_AUTHORIZER_CONTEXT, "true").lower() == "true"
133150
)
134-
self.cold_start_tracing = (
135-
os.environ.get("DD_COLD_START_TRACING", "true").lower() == "true"
151+
self.cold_start_tracing = depends_on_dd_tracing_enabled(
152+
os.environ.get(DD_COLD_START_TRACING, "true").lower() == "true"
136153
)
137154
self.min_cold_start_trace_duration = 3
138-
if "DD_MIN_COLD_START_DURATION" in os.environ:
155+
if DD_MIN_COLD_START_DURATION in os.environ:
139156
try:
140157
self.min_cold_start_trace_duration = int(
141-
os.environ["DD_MIN_COLD_START_DURATION"]
158+
os.environ[DD_MIN_COLD_START_DURATION]
142159
)
143160
except Exception:
144-
logger.debug("Malformatted env DD_MIN_COLD_START_DURATION")
161+
logger.debug(f"Malformatted env {DD_MIN_COLD_START_DURATION}")
145162
self.cold_start_trace_skip_lib = [
146163
"ddtrace.internal.compat",
147164
"ddtrace.filters",
148165
]
149-
if "DD_COLD_START_TRACE_SKIP_LIB" in os.environ:
166+
if DD_COLD_START_TRACE_SKIP_LIB in os.environ:
150167
try:
151168
self.cold_start_trace_skip_lib = os.environ[
152-
"DD_COLD_START_TRACE_SKIP_LIB"
169+
DD_COLD_START_TRACE_SKIP_LIB
153170
].split(",")
154171
except Exception:
155-
logger.debug("Malformatted for env DD_COLD_START_TRACE_SKIP_LIB")
172+
logger.debug(f"Malformatted for env {DD_COLD_START_TRACE_SKIP_LIB}")
156173
self.response = None
157174
if profiling_env_var:
158175
self.prof = profiler.Profiler(env=env_env_var, service=service_env_var)
@@ -170,8 +187,8 @@ def __init__(self, func):
170187

171188
# This prevents a breaking change in ddtrace v0.49 regarding the service name
172189
# in requests-related spans
173-
os.environ["DD_REQUESTS_SERVICE_NAME"] = os.environ.get(
174-
"DD_SERVICE", "aws.lambda"
190+
os.environ[DD_REQUESTS_SERVICE_NAME] = os.environ.get(
191+
DD_SERVICE, "aws.lambda"
175192
)
176193
# Patch third-party libraries for tracing
177194
patch_all()

tests/test_wrapper.py

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from unittest.mock import patch, call, ANY, MagicMock
77
from datadog_lambda.constants import TraceHeader
88

9-
from datadog_lambda.wrapper import datadog_lambda_wrapper
9+
import datadog_lambda.wrapper as wrapper
1010
from datadog_lambda.metric import lambda_metric
1111
from datadog_lambda.thread_stats_writer import ThreadStatsWriter
1212

@@ -31,8 +31,11 @@ class TestDatadogLambdaWrapper(unittest.TestCase):
3131
def setUp(self):
3232
# Force @datadog_lambda_wrapper to always create a real
3333
# (not no-op) wrapper.
34-
datadog_lambda_wrapper._force_wrap = True
34+
patch("ddtrace.internal.remoteconfig.RemoteConfig").start()
35+
patch("ddtrace.internal.writer.AgentWriter.flush_queue").start()
3536

37+
wrapper.datadog_lambda_wrapper._force_wrap = True
38+
wrapper.dd_tracing_enabled = True
3639
patcher = patch(
3740
"datadog.threadstats.reporters.HttpReporter.flush_distributions"
3841
)
@@ -84,7 +87,9 @@ def setUp(self):
8487
self.addCleanup(patcher.stop)
8588

8689
def test_datadog_lambda_wrapper(self):
87-
@datadog_lambda_wrapper
90+
wrapper.dd_tracing_enabled = False
91+
92+
@wrapper.datadog_lambda_wrapper
8893
def lambda_handler(event, context):
8994
lambda_metric("test.metric", 100)
9095

@@ -93,7 +98,7 @@ def lambda_handler(event, context):
9398
lambda_context = get_mock_context()
9499

95100
lambda_handler(lambda_event, lambda_context)
96-
101+
wrapper.dd_tracing_enabled = True
97102
self.mock_threadstats_flush_distributions.assert_has_calls(
98103
[
99104
call(
@@ -112,7 +117,10 @@ def lambda_handler(event, context):
112117
]
113118
)
114119
self.mock_extract_dd_trace_context.assert_called_with(
115-
lambda_event, lambda_context, extractor=None, decode_authorizer_context=True
120+
lambda_event,
121+
lambda_context,
122+
extractor=None,
123+
decode_authorizer_context=False,
116124
)
117125
self.mock_set_correlation_ids.assert_called()
118126
self.mock_inject_correlation_ids.assert_called()
@@ -121,7 +129,7 @@ def lambda_handler(event, context):
121129
def test_datadog_lambda_wrapper_flush_to_log(self):
122130
os.environ["DD_FLUSH_TO_LOG"] = "True"
123131

124-
@datadog_lambda_wrapper
132+
@wrapper.datadog_lambda_wrapper
125133
def lambda_handler(event, context):
126134
lambda_metric("test.metric", 100)
127135

@@ -139,7 +147,7 @@ def test_datadog_lambda_wrapper_flush_in_thread(self):
139147
metric_module.lambda_stats.stop()
140148
metric_module.lambda_stats = ThreadStatsWriter(True)
141149

142-
@datadog_lambda_wrapper
150+
@wrapper.datadog_lambda_wrapper
143151
def lambda_handler(event, context):
144152
import time
145153

@@ -166,7 +174,7 @@ def test_datadog_lambda_wrapper_not_flush_in_thread(self):
166174
metric_module.lambda_stats.stop()
167175
metric_module.lambda_stats = ThreadStatsWriter(False)
168176

169-
@datadog_lambda_wrapper
177+
@wrapper.datadog_lambda_wrapper
170178
def lambda_handler(event, context):
171179
import time
172180

@@ -188,21 +196,22 @@ def lambda_handler(event, context):
188196

189197
def test_datadog_lambda_wrapper_inject_correlation_ids(self):
190198
os.environ["DD_LOGS_INJECTION"] = "True"
199+
wrapper.dd_tracing_enabled = False
191200

192-
@datadog_lambda_wrapper
201+
@wrapper.datadog_lambda_wrapper
193202
def lambda_handler(event, context):
194203
lambda_metric("test.metric", 100)
195204

196205
lambda_event = {}
197206
lambda_handler(lambda_event, get_mock_context())
198-
207+
wrapper.dd_tracing_enabled = True
199208
self.mock_set_correlation_ids.assert_called()
200209
self.mock_inject_correlation_ids.assert_called()
201210

202211
del os.environ["DD_LOGS_INJECTION"]
203212

204213
def test_invocations_metric(self):
205-
@datadog_lambda_wrapper
214+
@wrapper.datadog_lambda_wrapper
206215
def lambda_handler(event, context):
207216
lambda_metric("test.metric", 100)
208217

@@ -232,7 +241,7 @@ def lambda_handler(event, context):
232241
)
233242

234243
def test_errors_metric(self):
235-
@datadog_lambda_wrapper
244+
@wrapper.datadog_lambda_wrapper
236245
def lambda_handler(event, context):
237246
raise RuntimeError()
238247

@@ -288,7 +297,7 @@ def test_5xx_sends_errors_metric_and_set_tags(self, mock_extract_trigger_tags):
288297
"http.method": "GET",
289298
}
290299

291-
@datadog_lambda_wrapper
300+
@wrapper.datadog_lambda_wrapper
292301
def lambda_handler(event, context):
293302
return {"statusCode": 500, "body": "fake response body"}
294303

@@ -334,7 +343,7 @@ def lambda_handler(event, context):
334343
)
335344

336345
def test_enhanced_metrics_cold_start_tag(self):
337-
@datadog_lambda_wrapper
346+
@wrapper.datadog_lambda_wrapper
338347
def lambda_handler(event, context):
339348
lambda_metric("test.metric", 100)
340349

@@ -386,7 +395,7 @@ def lambda_handler(event, context):
386395
)
387396

388397
def test_enhanced_metrics_latest(self):
389-
@datadog_lambda_wrapper
398+
@wrapper.datadog_lambda_wrapper
390399
def lambda_handler(event, context):
391400
lambda_metric("test.metric", 100)
392401

@@ -420,7 +429,7 @@ def lambda_handler(event, context):
420429
)
421430

422431
def test_enhanced_metrics_alias(self):
423-
@datadog_lambda_wrapper
432+
@wrapper.datadog_lambda_wrapper
424433
def lambda_handler(event, context):
425434
lambda_metric("test.metric", 100)
426435

@@ -456,7 +465,7 @@ def lambda_handler(event, context):
456465
def test_no_enhanced_metrics_without_env_var(self):
457466
os.environ["DD_ENHANCED_METRICS"] = "false"
458467

459-
@datadog_lambda_wrapper
468+
@wrapper.datadog_lambda_wrapper
460469
def lambda_handler(event, context):
461470
raise RuntimeError()
462471

@@ -474,15 +483,15 @@ def test_only_one_wrapper_in_use(self):
474483
self.mock_submit_invocations_metric = patcher.start()
475484
self.addCleanup(patcher.stop)
476485

477-
@datadog_lambda_wrapper
486+
@wrapper.datadog_lambda_wrapper
478487
def lambda_handler(event, context):
479488
lambda_metric("test.metric", 100)
480489

481490
# Turn off _force_wrap to emulate the nested wrapper scenario,
482491
# the second @datadog_lambda_wrapper should actually be no-op.
483-
datadog_lambda_wrapper._force_wrap = False
492+
wrapper.datadog_lambda_wrapper._force_wrap = False
484493

485-
lambda_handler_double_wrapped = datadog_lambda_wrapper(lambda_handler)
494+
lambda_handler_double_wrapped = wrapper.datadog_lambda_wrapper(lambda_handler)
486495

487496
lambda_event = {}
488497

@@ -492,7 +501,7 @@ def lambda_handler(event, context):
492501
self.mock_submit_invocations_metric.assert_called_once()
493502

494503
def test_dd_requests_service_name_default(self):
495-
@datadog_lambda_wrapper
504+
@wrapper.datadog_lambda_wrapper
496505
def lambda_handler(event, context):
497506
pass
498507

@@ -501,15 +510,15 @@ def lambda_handler(event, context):
501510
def test_dd_requests_service_name_set(self):
502511
os.environ["DD_SERVICE"] = "myAwesomeService"
503512

504-
@datadog_lambda_wrapper
513+
@wrapper.datadog_lambda_wrapper
505514
def lambda_handler(event, context):
506515
pass
507516

508517
self.assertEqual(os.environ.get("DD_REQUESTS_SERVICE_NAME"), "myAwesomeService")
509518
del os.environ["DD_SERVICE"]
510519

511520
def test_encode_authorizer_span(self):
512-
@datadog_lambda_wrapper
521+
@wrapper.datadog_lambda_wrapper
513522
def lambda_handler(event, context):
514523
return {
515524
"principalId": "foo",
@@ -537,7 +546,7 @@ def lambda_handler(event, context):
537546
mock_span.start_ns = 1668127541671386817
538547
mock_span.duration_ns = 1e8
539548
lambda_handler.inferred_span = mock_span
540-
549+
lambda_handler.make_inferred_span = False
541550
result = lambda_handler(lambda_event, lambda_context)
542551
inject_data = json.loads(base64.b64decode(result["context"]["_datadog"]))
543552
self.assertEquals(inject_data[TraceHeader.PARENT_ID], "123")
@@ -551,10 +560,22 @@ def test_different_return_type_no_error(self, MockPrintExc):
551560
mock_context = get_mock_context()
552561
for test_result in TEST_RESULTS:
553562

554-
@datadog_lambda_wrapper
563+
@wrapper.datadog_lambda_wrapper
555564
def return_type_test(event, context):
556565
return test_result
557566

558567
result = return_type_test({}, mock_context)
559568
self.assertEquals(result, test_result)
560569
self.assertFalse(MockPrintExc.called)
570+
571+
572+
class TestLambdaDecoratorSettings(unittest.TestCase):
573+
def test_some_envs_should_depend_on_dd_tracing_enabled(self):
574+
wrapper.dd_tracing_enabled = False
575+
os.environ[wrapper.DD_TRACE_MANAGED_SERVICES] = "true"
576+
os.environ[wrapper.DD_ENCODE_AUTHORIZER_CONTEXT] = "true"
577+
os.environ[wrapper.DD_DECODE_AUTHORIZER_CONTEXT] = "true"
578+
decorator = wrapper._LambdaDecorator(func=None)
579+
self.assertFalse(decorator.make_inferred_span)
580+
self.assertFalse(decorator.encode_authorizer_context)
581+
self.assertFalse(decorator.decode_authorizer_context)

0 commit comments

Comments
 (0)