@@ -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 :
@@ -93,6 +89,7 @@ def __init__(self, span: Optional[Span] = None, rc_products: str = ""):
93
89
logger .warning (WARNING_TAGS .ASM_ENV_NO_SPAN , extra = log_extra , stack_info = True )
94
90
raise TypeError ("ASM_Environment requires a span" )
95
91
self .span : Span = context_span
92
+ self .entry_span : Span = self .span ._service_entry_span
96
93
if self .span .name .endswith (".request" ):
97
94
self .framework = self .span .name [:- 8 ]
98
95
else :
@@ -132,6 +129,17 @@ def get_blocked() -> Dict[str, Any]:
132
129
return env .blocked or {}
133
130
134
131
132
+ def get_entry_span () -> Optional [Span ]:
133
+ env = _get_asm_context ()
134
+ if env is None :
135
+ span = core .get_span ()
136
+ if span :
137
+ return span ._service_entry_span
138
+ else :
139
+ return core .get_root_span ()
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,41 @@ 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
204
+ entry_span = env .entry_span
198
205
if env .waf_triggers :
199
- report_list = get_triggers (root_span )
206
+ report_list = get_triggers (entry_span )
200
207
if report_list is not None :
201
208
report_list .extend (env .waf_triggers )
202
209
else :
203
210
report_list = env .waf_triggers
204
211
if asm_config ._use_metastruct_for_triggers :
205
- root_span .set_struct_tag (APPSEC .STRUCT , {"triggers" : report_list })
212
+ entry_span .set_struct_tag (APPSEC .STRUCT , {"triggers" : report_list })
206
213
else :
207
- root_span .set_tag (APPSEC .JSON , json .dumps ({"triggers" : report_list }, separators = ("," , ":" )))
214
+ entry_span .set_tag (APPSEC .JSON , json .dumps ({"triggers" : report_list }, separators = ("," , ":" )))
208
215
env .waf_triggers = []
209
216
telemetry_results : Telemetry_result = env .telemetry
210
217
211
- root_span .set_tag_str (APPSEC .WAF_VERSION , ddwaf_version )
218
+ entry_span .set_tag_str (APPSEC .WAF_VERSION , ddwaf_version )
212
219
if telemetry_results .total_duration :
213
- update_span_metrics (root_span , APPSEC .WAF_DURATION , telemetry_results .duration )
220
+ update_span_metrics (entry_span , APPSEC .WAF_DURATION , telemetry_results .duration )
214
221
telemetry_results .duration = 0.0
215
- update_span_metrics (root_span , APPSEC .WAF_DURATION_EXT , telemetry_results .total_duration )
222
+ update_span_metrics (entry_span , APPSEC .WAF_DURATION_EXT , telemetry_results .total_duration )
216
223
telemetry_results .total_duration = 0.0
217
224
if telemetry_results .timeout :
218
- update_span_metrics (root_span , APPSEC .WAF_TIMEOUTS , telemetry_results .timeout )
225
+ update_span_metrics (entry_span , APPSEC .WAF_TIMEOUTS , telemetry_results .timeout )
219
226
rasp_timeouts = sum (telemetry_results .rasp .timeout .values ())
220
227
if rasp_timeouts :
221
- update_span_metrics (root_span , APPSEC .RASP_TIMEOUTS , rasp_timeouts )
228
+ update_span_metrics (entry_span , APPSEC .RASP_TIMEOUTS , rasp_timeouts )
222
229
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 )
230
+ update_span_metrics (entry_span , APPSEC .RASP_DURATION , telemetry_results .rasp .duration )
231
+ update_span_metrics (entry_span , APPSEC .RASP_DURATION_EXT , telemetry_results .rasp .total_duration )
232
+ update_span_metrics (entry_span , APPSEC .RASP_RULE_EVAL , telemetry_results .rasp .sum_eval )
226
233
if telemetry_results .truncation .string_length :
227
- root_span .set_metric (APPSEC .TRUNCATION_STRING_LENGTH , max (telemetry_results .truncation .string_length ))
234
+ entry_span .set_metric (APPSEC .TRUNCATION_STRING_LENGTH , max (telemetry_results .truncation .string_length ))
228
235
if telemetry_results .truncation .container_size :
229
- root_span .set_metric (APPSEC .TRUNCATION_CONTAINER_SIZE , max (telemetry_results .truncation .container_size ))
236
+ entry_span .set_metric (APPSEC .TRUNCATION_CONTAINER_SIZE , max (telemetry_results .truncation .container_size ))
230
237
if telemetry_results .truncation .container_depth :
231
- root_span .set_metric (APPSEC .TRUNCATION_CONTAINER_DEPTH , max (telemetry_results .truncation .container_depth ))
238
+ entry_span .set_metric (APPSEC .TRUNCATION_CONTAINER_DEPTH , max (telemetry_results .truncation .container_depth ))
232
239
233
240
234
241
def finalize_asm_env (env : ASM_Environment ) -> None :
@@ -240,31 +247,31 @@ def finalize_asm_env(env: ASM_Environment) -> None:
240
247
flush_waf_triggers (env )
241
248
for function in env .callbacks [_CONTEXT_CALL ]:
242
249
function (env )
243
- root_span = env .span . _local_root or env . span
244
- if root_span :
250
+ entry_span = env .entry_span
251
+ if entry_span :
245
252
if env .waf_info :
246
253
info = env .waf_info ()
247
254
try :
248
255
if info .errors :
249
- root_span .set_tag_str (APPSEC .EVENT_RULE_ERRORS , info .errors )
256
+ entry_span .set_tag_str (APPSEC .EVENT_RULE_ERRORS , info .errors )
250
257
extra = {"product" : "appsec" , "more_info" : info .errors , "stack_limit" : 4 }
251
258
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 )
259
+ entry_span .set_tag_str (APPSEC .EVENT_RULE_VERSION , info .version )
260
+ entry_span .set_metric (APPSEC .EVENT_RULE_LOADED , info .loaded )
261
+ entry_span .set_metric (APPSEC .EVENT_RULE_ERROR_COUNT , info .failed )
255
262
except Exception :
256
263
logger .debug ("asm_context::finalize_asm_env::exception" , extra = log_extra , exc_info = True )
257
264
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 )
265
+ entry_span .set_tag (APPSEC .RC_CLIENT_ID , asm_config ._rc_client_id )
259
266
waf_adresses = env .waf_addresses
260
267
req_headers = waf_adresses .get (SPAN_DATA_NAMES .REQUEST_HEADERS_NO_COOKIES , {})
261
268
if req_headers :
262
- _set_headers (root_span , req_headers , kind = "request" )
269
+ _set_headers (entry_span , req_headers , kind = "request" )
263
270
res_headers = waf_adresses .get (SPAN_DATA_NAMES .RESPONSE_HEADERS_NO_COOKIES , {})
264
271
if res_headers :
265
- _set_headers (root_span , res_headers , kind = "response" )
272
+ _set_headers (entry_span , res_headers , kind = "response" )
266
273
if env .rc_products :
267
- root_span .set_tag_str (APPSEC .RC_PRODUCTS , env .rc_products )
274
+ entry_span .set_tag_str (APPSEC .RC_PRODUCTS , env .rc_products )
268
275
269
276
core .discard_local_item (_ASM_CONTEXT )
270
277
@@ -364,7 +371,7 @@ def call_waf_callback(custom_data: Optional[Dict[str, Any]] = None, **kwargs) ->
364
371
return callback (custom_data , ** kwargs )
365
372
else :
366
373
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 )
374
+ report_error_on_entry_span ("appsec::instrumentation::diagnostic" , WARNING_TAGS .CALL_WAF_CALLBACK_NOT_SET )
368
375
return None
369
376
370
377
@@ -661,7 +668,7 @@ def _set_headers(span: Span, headers: Any, kind: str, only_asm_enabled: bool = F
661
668
value = value .decode ()
662
669
if key .lower () in (_COLLECTED_REQUEST_HEADERS_ASM_ENABLED if only_asm_enabled else _COLLECTED_REQUEST_HEADERS ):
663
670
# 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 )
671
+ span .set_tag (_normalize_tag_name (kind , key ), value )
665
672
666
673
667
674
def asm_listen ():
0 commit comments