Skip to content

Commit 2b4a835

Browse files
brettlangdonchristophe-papazianmabdinur
authored
fix(asm): simplify asm request context span registration [backport #5822 to 1.13] (#5826)
Backport of #5822 to 1.13 Remove the use of span context._meta to store information about context registration. update tests for asm request context to unit test the new registration process. ## Checklist - [x] Change(s) are motivated and described in the PR description. - [x] Testing strategy is described if automated tests are not included in the PR. - [x] Risk is outlined (performance impact, potential for breakage, maintainability, etc). - [x] Change is maintainable (easy to change, telemetry, documentation). - [x] [Library release note guidelines](https://ddtrace.readthedocs.io/en/stable/contributing.html#Release-Note-Guidelines) are followed. - [x] Documentation is included (in-code, generated user docs, [public corp docs](https://github.com/DataDog/documentation/)). - [x] OPTIONAL: PR description includes explicit acknowledgement of the performance implications of the change as reported in the benchmarks PR comment. ## Reviewer Checklist - [x] Title is accurate. - [x] No unnecessary changes are introduced. - [x] Description motivates each change. - [x] Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes unless absolutely necessary. - [x] Testing strategy adequately addresses listed risk(s). - [x] Change is maintainable (easy to change, telemetry, documentation). - [x] Release note makes sense to a user of the library. - [x] Reviewer has explicitly acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment. --------- Co-authored-by: Christophe Papazian <[email protected]> Co-authored-by: Munir Abdinur <[email protected]>
1 parent 81be3fe commit 2b4a835

File tree

4 files changed

+19
-12
lines changed

4 files changed

+19
-12
lines changed

ddtrace/appsec/_asm_request_context.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class ASM_Environment:
5353
def __init__(self, active=False): # type: (bool) -> None
5454
self.active = active
5555
self.span = None
56+
self.span_asm_context = None # type: None | contextlib.AbstractContextManager
5657
self.waf_addresses = {} # type: dict[str, Any]
5758
self.callbacks = {} # type: dict[str, Any]
5859
self.telemetry = {} # type: dict[str, Any]
@@ -82,12 +83,19 @@ def is_blocked(): # type: () -> bool
8283
return False
8384

8485

85-
def register(span):
86+
def register(span, span_asm_context=None):
8687
env = _ASM.get()
8788
if not env.active:
8889
log.debug("registering a span with no active asm context")
8990
return
9091
env.span = span
92+
env.span_asm_context = span_asm_context
93+
94+
95+
def unregister(span):
96+
env = _ASM.get()
97+
if env.span_asm_context is not None and env.span is span:
98+
env.span_asm_context.__exit__(None, None, None)
9199

92100

93101
class _DataHandler:

ddtrace/appsec/processor.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,7 @@ def on_span_start(self, span):
220220
else:
221221
new_asm_context = _asm_request_context.asm_request_context_manager()
222222
new_asm_context.__enter__()
223-
span.context._meta["ASM_CONTEXT_%d" % id(span)] = new_asm_context # type: ignore
224-
_asm_request_context.register(span)
223+
_asm_request_context.register(span, new_asm_context)
225224

226225
ctx = self._ddwaf._at_request_start()
227226

@@ -376,7 +375,6 @@ def _is_needed(self, address):
376375

377376
def on_span_finish(self, span):
378377
# type: (Span) -> None
379-
asm_context = span.context._meta.get("ASM_CONTEXT_%d" % id(span), None)
380378
try:
381379
if span.span_type == SpanTypes.WEB:
382380
# Force to set respond headers at the end
@@ -392,6 +390,4 @@ def on_span_finish(self, span):
392390
self._ddwaf._at_request_end()
393391
finally:
394392
# release asm context if it was created by the span
395-
if asm_context is not None:
396-
asm_context.__exit__(None, None, None) # type: ignore
397-
del span.context._meta["ASM_CONTEXT_%d" % id(span)]
393+
_asm_request_context.unregister(span)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fixes:
2+
- |
3+
ASM: Fixes encoding error when using AppSec and a trace is partial flushed.

tests/appsec/test_processor.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -654,16 +654,16 @@ def test_ddwaf_run_contained_oserror(tracer_appsec, caplog):
654654
assert "OSError: ddwaf run failed" in caplog.text
655655

656656

657-
def test_asm_context_meta(tracer_appsec):
657+
def test_asm_context_registration(tracer_appsec):
658658
tracer = tracer_appsec
659659

660660
# For a web type span, a context manager is added, but then removed
661661
with tracer.trace("test", span_type=SpanTypes.WEB) as span:
662-
assert span.context._meta["ASM_CONTEXT_%d" % (id(span),)]
663-
assert span.context._meta.get("ASM_CONTEXT_%d" % (id(span),)) is None
662+
assert _asm_request_context._ASM.get().span_asm_context
663+
assert _asm_request_context._ASM.get().span_asm_context is None
664664

665665
# Regression test, if the span type changes after being created, we always removed
666666
with tracer.trace("test", span_type=SpanTypes.WEB) as span:
667667
span.span_type = SpanTypes.HTTP
668-
assert span.context._meta["ASM_CONTEXT_%d" % (id(span),)]
669-
assert span.context._meta.get("ASM_CONTEXT_%d" % (id(span),)) is None
668+
assert _asm_request_context._ASM.get().span_asm_context
669+
assert _asm_request_context._ASM.get().span_asm_context is None

0 commit comments

Comments
 (0)