Skip to content

Commit cdc2aa3

Browse files
brettlangdonchristophe-papazianmabdinur
authored
fix(asm): simplify asm request context span registration [backport #5822 to 1.12] (#5827)
Backport of #5822 to 1.12 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 8c713ac commit cdc2aa3

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
@@ -37,6 +37,7 @@ class ASM_Environment:
3737
def __init__(self, active=False): # type: (bool) -> None
3838
self.active = active
3939
self.span = None
40+
self.span_asm_context = None # type: None | contextlib.AbstractContextManager
4041
self.waf_addresses = {} # type: dict[str, Any]
4142
self.callbacks = {} # type: dict[str, Any]
4243
self.telemetry = {} # type: dict[str, Any]
@@ -51,12 +52,19 @@ def free_context_available(): # type: () -> bool
5152
return env.active and env.span is None
5253

5354

54-
def register(span):
55+
def register(span, span_asm_context=None):
5556
env = _ASM.get()
5657
if not env.active:
5758
log.debug("registering a span with no active asm context")
5859
return
5960
env.span = span
61+
env.span_asm_context = span_asm_context
62+
63+
64+
def unregister(span):
65+
env = _ASM.get()
66+
if env.span_asm_context is not None and env.span is span:
67+
env.span_asm_context.__exit__(None, None, None)
6068

6169

6270
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

@@ -379,7 +378,6 @@ def _is_needed(self, address):
379378

380379
def on_span_finish(self, span):
381380
# type: (Span) -> None
382-
asm_context = span.context._meta.get("ASM_CONTEXT_%d" % id(span), None)
383381
try:
384382
if span.span_type != SpanTypes.WEB:
385383
return
@@ -396,6 +394,4 @@ def on_span_finish(self, span):
396394
self._ddwaf._at_request_end()
397395
finally:
398396
# release asm context if it was created by the span
399-
if asm_context is not None:
400-
asm_context.__exit__(None, None, None) # type: ignore
401-
del span.context._meta["ASM_CONTEXT_%d" % id(span)]
397+
_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)