@@ -64,16 +64,12 @@ class WARNING_TAGS(metaclass=Constant_Class):
64
64
GLOBAL_CALLBACKS : Dict [str , List [Callable ]] = {_CONTEXT_CALL : []}
65
65
66
66
67
- def report_error_on_span (error : str , message : str ) -> None :
68
- span = getattr (_get_asm_context (), "span" , None ) or core .get_span ()
69
- if not span :
70
- root_span = core .get_root_span ()
71
- else :
72
- root_span = span ._local_root or span
73
- if not root_span :
67
+ def report_error_on_entry_span (error : str , message : str ) -> None :
68
+ entry_span = get_entry_span ()
69
+ if not entry_span :
74
70
return
75
- root_span .set_tag_str (APPSEC .ERROR_TYPE , error )
76
- root_span .set_tag_str (APPSEC .ERROR_MESSAGE , message )
71
+ entry_span .set_tag_str (APPSEC .ERROR_TYPE , error )
72
+ entry_span .set_tag_str (APPSEC .ERROR_MESSAGE , message )
77
73
78
74
79
75
class ASM_Environment :
@@ -109,6 +105,10 @@ def __init__(self, span: Optional[Span] = None, rc_products: str = ""):
109
105
self .api_security_reported : int = 0
110
106
self .rc_products : str = rc_products
111
107
108
+ @property
109
+ def entry_span (self ):
110
+ return self .span ._service_entry_span
111
+
112
112
113
113
def _get_asm_context () -> Optional [ASM_Environment ]:
114
114
return core .get_item (_ASM_CONTEXT )
@@ -132,6 +132,14 @@ def get_blocked() -> Dict[str, Any]:
132
132
return env .blocked or {}
133
133
134
134
135
+ def get_entry_span () -> Optional [Span ]:
136
+ env = _get_asm_context ()
137
+ if env is None :
138
+ span = core .get_span ()
139
+ return span ._service_entry_span if span else None
140
+ return env .entry_span
141
+
142
+
135
143
def get_framework () -> str :
136
144
env = _get_asm_context ()
137
145
if env is None :
@@ -193,42 +201,40 @@ def update_span_metrics(span: Span, name: str, value: Union[float, int]) -> None
193
201
def flush_waf_triggers (env : ASM_Environment ) -> None :
194
202
from ddtrace .appsec ._metrics import ddwaf_version
195
203
196
- # Make sure we find a root span to attach the triggers to
197
- root_span = env .span ._local_root or env .span
198
204
if env .waf_triggers :
199
- report_list = get_triggers (root_span )
205
+ report_list = get_triggers (env . entry_span )
200
206
if report_list is not None :
201
207
report_list .extend (env .waf_triggers )
202
208
else :
203
209
report_list = env .waf_triggers
204
210
if asm_config ._use_metastruct_for_triggers :
205
- root_span .set_struct_tag (APPSEC .STRUCT , {"triggers" : report_list })
211
+ env . entry_span .set_struct_tag (APPSEC .STRUCT , {"triggers" : report_list })
206
212
else :
207
- root_span .set_tag (APPSEC .JSON , json .dumps ({"triggers" : report_list }, separators = ("," , ":" )))
213
+ env . entry_span .set_tag (APPSEC .JSON , json .dumps ({"triggers" : report_list }, separators = ("," , ":" )))
208
214
env .waf_triggers = []
209
215
telemetry_results : Telemetry_result = env .telemetry
210
216
211
- root_span .set_tag_str (APPSEC .WAF_VERSION , ddwaf_version )
217
+ env . entry_span .set_tag_str (APPSEC .WAF_VERSION , ddwaf_version )
212
218
if telemetry_results .total_duration :
213
- update_span_metrics (root_span , APPSEC .WAF_DURATION , telemetry_results .duration )
219
+ update_span_metrics (env . entry_span , APPSEC .WAF_DURATION , telemetry_results .duration )
214
220
telemetry_results .duration = 0.0
215
- update_span_metrics (root_span , APPSEC .WAF_DURATION_EXT , telemetry_results .total_duration )
221
+ update_span_metrics (env . entry_span , APPSEC .WAF_DURATION_EXT , telemetry_results .total_duration )
216
222
telemetry_results .total_duration = 0.0
217
223
if telemetry_results .timeout :
218
- update_span_metrics (root_span , APPSEC .WAF_TIMEOUTS , telemetry_results .timeout )
224
+ update_span_metrics (env . entry_span , APPSEC .WAF_TIMEOUTS , telemetry_results .timeout )
219
225
rasp_timeouts = sum (telemetry_results .rasp .timeout .values ())
220
226
if rasp_timeouts :
221
- update_span_metrics (root_span , APPSEC .RASP_TIMEOUTS , rasp_timeouts )
227
+ update_span_metrics (env . entry_span , APPSEC .RASP_TIMEOUTS , rasp_timeouts )
222
228
if telemetry_results .rasp .sum_eval :
223
- update_span_metrics (root_span , APPSEC .RASP_DURATION , telemetry_results .rasp .duration )
224
- update_span_metrics (root_span , APPSEC .RASP_DURATION_EXT , telemetry_results .rasp .total_duration )
225
- update_span_metrics (root_span , APPSEC .RASP_RULE_EVAL , telemetry_results .rasp .sum_eval )
229
+ update_span_metrics (env . entry_span , APPSEC .RASP_DURATION , telemetry_results .rasp .duration )
230
+ update_span_metrics (env . entry_span , APPSEC .RASP_DURATION_EXT , telemetry_results .rasp .total_duration )
231
+ update_span_metrics (env . entry_span , APPSEC .RASP_RULE_EVAL , telemetry_results .rasp .sum_eval )
226
232
if telemetry_results .truncation .string_length :
227
- root_span .set_metric (APPSEC .TRUNCATION_STRING_LENGTH , max (telemetry_results .truncation .string_length ))
233
+ env . entry_span .set_metric (APPSEC .TRUNCATION_STRING_LENGTH , max (telemetry_results .truncation .string_length ))
228
234
if telemetry_results .truncation .container_size :
229
- root_span .set_metric (APPSEC .TRUNCATION_CONTAINER_SIZE , max (telemetry_results .truncation .container_size ))
235
+ env . entry_span .set_metric (APPSEC .TRUNCATION_CONTAINER_SIZE , max (telemetry_results .truncation .container_size ))
230
236
if telemetry_results .truncation .container_depth :
231
- root_span .set_metric (APPSEC .TRUNCATION_CONTAINER_DEPTH , max (telemetry_results .truncation .container_depth ))
237
+ env . entry_span .set_metric (APPSEC .TRUNCATION_CONTAINER_DEPTH , max (telemetry_results .truncation .container_depth ))
232
238
233
239
234
240
def finalize_asm_env (env : ASM_Environment ) -> None :
@@ -240,31 +246,30 @@ def finalize_asm_env(env: ASM_Environment) -> None:
240
246
flush_waf_triggers (env )
241
247
for function in env .callbacks [_CONTEXT_CALL ]:
242
248
function (env )
243
- root_span = env .span ._local_root or env .span
244
- if root_span :
249
+ if env .entry_span :
245
250
if env .waf_info :
246
251
info = env .waf_info ()
247
252
try :
248
253
if info .errors :
249
- root_span .set_tag_str (APPSEC .EVENT_RULE_ERRORS , info .errors )
254
+ env . entry_span .set_tag_str (APPSEC .EVENT_RULE_ERRORS , info .errors )
250
255
extra = {"product" : "appsec" , "more_info" : info .errors , "stack_limit" : 4 }
251
256
logger .debug ("asm_context::finalize_asm_env::waf_errors" , extra = extra , stack_info = True )
252
- root_span .set_tag_str (APPSEC .EVENT_RULE_VERSION , info .version )
253
- root_span .set_metric (APPSEC .EVENT_RULE_LOADED , info .loaded )
254
- root_span .set_metric (APPSEC .EVENT_RULE_ERROR_COUNT , info .failed )
257
+ env . entry_span .set_tag_str (APPSEC .EVENT_RULE_VERSION , info .version )
258
+ env . entry_span .set_metric (APPSEC .EVENT_RULE_LOADED , info .loaded )
259
+ env . entry_span .set_metric (APPSEC .EVENT_RULE_ERROR_COUNT , info .failed )
255
260
except Exception :
256
261
logger .debug ("asm_context::finalize_asm_env::exception" , extra = log_extra , exc_info = True )
257
262
if asm_config ._rc_client_id is not None :
258
- root_span . _local_root .set_tag (APPSEC .RC_CLIENT_ID , asm_config ._rc_client_id )
263
+ env . entry_span .set_tag (APPSEC .RC_CLIENT_ID , asm_config ._rc_client_id )
259
264
waf_adresses = env .waf_addresses
260
265
req_headers = waf_adresses .get (SPAN_DATA_NAMES .REQUEST_HEADERS_NO_COOKIES , {})
261
266
if req_headers :
262
- _set_headers (root_span , req_headers , kind = "request" )
267
+ _set_headers (env . entry_span , req_headers , kind = "request" )
263
268
res_headers = waf_adresses .get (SPAN_DATA_NAMES .RESPONSE_HEADERS_NO_COOKIES , {})
264
269
if res_headers :
265
- _set_headers (root_span , res_headers , kind = "response" )
270
+ _set_headers (env . entry_span , res_headers , kind = "response" )
266
271
if env .rc_products :
267
- root_span .set_tag_str (APPSEC .RC_PRODUCTS , env .rc_products )
272
+ env . entry_span .set_tag_str (APPSEC .RC_PRODUCTS , env .rc_products )
268
273
269
274
core .discard_local_item (_ASM_CONTEXT )
270
275
@@ -364,7 +369,7 @@ def call_waf_callback(custom_data: Optional[Dict[str, Any]] = None, **kwargs) ->
364
369
return callback (custom_data , ** kwargs )
365
370
else :
366
371
logger .warning (WARNING_TAGS .CALL_WAF_CALLBACK_NOT_SET , extra = log_extra , stack_info = True )
367
- report_error_on_span ("appsec::instrumentation::diagnostic" , WARNING_TAGS .CALL_WAF_CALLBACK_NOT_SET )
372
+ report_error_on_entry_span ("appsec::instrumentation::diagnostic" , WARNING_TAGS .CALL_WAF_CALLBACK_NOT_SET )
368
373
return None
369
374
370
375
@@ -661,7 +666,7 @@ def _set_headers(span: Span, headers: Any, kind: str, only_asm_enabled: bool = F
661
666
value = value .decode ()
662
667
if key .lower () in (_COLLECTED_REQUEST_HEADERS_ASM_ENABLED if only_asm_enabled else _COLLECTED_REQUEST_HEADERS ):
663
668
# since the header value can be a list, use `set_tag()` to ensure it is converted to a string
664
- ( span . _local_root or span ) .set_tag (_normalize_tag_name (kind , key ), value )
669
+ span .set_tag (_normalize_tag_name (kind , key ), value )
665
670
666
671
667
672
def asm_listen ():
0 commit comments