Skip to content

Commit d69069d

Browse files
ref(langchain): Remove WatchedSpan class
1 parent c686455 commit d69069d

1 file changed

Lines changed: 26 additions & 46 deletions

File tree

sentry_sdk/integrations/langchain.py

Lines changed: 26 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
from typing import TYPE_CHECKING
88

99
import sentry_sdk
10-
from sentry_sdk.ai.monitoring import set_ai_pipeline_name
1110
from sentry_sdk.ai.utils import (
1211
GEN_AI_ALLOWED_MESSAGE_ROLES,
1312
get_start_span_function,
@@ -241,22 +240,13 @@ def setup_once() -> None:
241240
_patch_embeddings_provider(OllamaEmbeddings)
242241

243242

244-
class WatchedSpan:
245-
span: "Span" = None # type: ignore[assignment]
246-
children: "List[WatchedSpan]" = []
247-
is_pipeline: bool = False
248-
249-
def __init__(self, span: "Span") -> None:
250-
self.span = span
251-
252-
253243
class SentryLangchainCallback(BaseCallbackHandler): # type: ignore[misc]
254244
"""Callback handler that creates Sentry spans."""
255245

256246
def __init__(
257247
self, max_span_map_size: "Optional[int]", include_prompts: bool
258248
) -> None:
259-
self.span_map: "OrderedDict[UUID, WatchedSpan]" = OrderedDict()
249+
self.span_map: "OrderedDict[UUID, sentry_sdk.tracing.Span]" = OrderedDict()
260250
self.max_span_map_size = max_span_map_size
261251
self.include_prompts = include_prompts
262252

@@ -271,8 +261,7 @@ def _handle_error(self, run_id: "UUID", error: "Any") -> None:
271261
if not run_id or run_id not in self.span_map:
272262
return
273263

274-
span_data = self.span_map[run_id]
275-
span = span_data.span
264+
span = self.span_map[run_id]
276265

277266
sentry_sdk.capture_exception(error, span.scope)
278267

@@ -291,29 +280,27 @@ def _create_span(
291280
run_id: "UUID",
292281
parent_id: "Optional[Any]",
293282
**kwargs: "Any",
294-
) -> "WatchedSpan":
295-
watched_span: "Optional[WatchedSpan]" = None
283+
) -> "sentry_sdk.tracing.Span":
284+
span = None
296285
if parent_id:
297-
parent_span: "Optional[WatchedSpan]" = self.span_map.get(parent_id)
286+
parent_span: "Optional[sentry_sdk.tracing.Span]" = self.span_map.get(
287+
parent_id
288+
)
298289
if parent_span:
299-
watched_span = WatchedSpan(parent_span.span.start_child(**kwargs))
300-
parent_span.children.append(watched_span)
290+
span = parent_span.span.start_child(**kwargs)
301291

302-
if watched_span is None:
303-
watched_span = WatchedSpan(sentry_sdk.start_span(**kwargs))
292+
if span is None:
293+
span = sentry_sdk.start_span(**kwargs)
304294

305-
watched_span.span.__enter__()
306-
self.span_map[run_id] = watched_span
295+
span.__enter__()
296+
self.span_map[run_id] = span
307297
self.gc_span_map()
308-
return watched_span
298+
return span
309299

310300
def _exit_span(
311-
self: "SentryLangchainCallback", span_data: "WatchedSpan", run_id: "UUID"
301+
self: "SentryLangchainCallback", span: "sentry_sdk.tracing.Span", run_id: "UUID"
312302
) -> None:
313-
if span_data.is_pipeline:
314-
set_ai_pipeline_name(None)
315-
316-
span_data.span.__exit__(None, None, None)
303+
span.__exit__(None, None, None)
317304
del self.span_map[run_id]
318305

319306
def on_llm_start(
@@ -341,14 +328,13 @@ def on_llm_start(
341328
or ""
342329
)
343330

344-
watched_span = self._create_span(
331+
span = self._create_span(
345332
run_id,
346333
parent_run_id,
347334
op=OP.GEN_AI_TEXT_COMPLETION,
348335
name=f"text_completion {model}".strip(),
349336
origin=LangchainIntegration.origin,
350337
)
351-
span = watched_span.span
352338

353339
span.set_data(SPANDATA.GEN_AI_OPERATION_NAME, "text_completion")
354340

@@ -421,14 +407,13 @@ def on_chat_model_start(
421407
or ""
422408
)
423409

424-
watched_span = self._create_span(
410+
span = self._create_span(
425411
run_id,
426412
kwargs.get("parent_run_id"),
427413
op=OP.GEN_AI_CHAT,
428414
name=f"chat {model}".strip(),
429415
origin=LangchainIntegration.origin,
430416
)
431-
span = watched_span.span
432417

433418
span.set_data(SPANDATA.GEN_AI_OPERATION_NAME, "chat")
434419
if model:
@@ -505,8 +490,7 @@ def on_chat_model_end(
505490
if not run_id or run_id not in self.span_map:
506491
return
507492

508-
span_data = self.span_map[run_id]
509-
span = span_data.span
493+
span = self.span_map[run_id]
510494

511495
if should_send_default_pii() and self.include_prompts:
512496
set_data_normalized(
@@ -516,7 +500,7 @@ def on_chat_model_end(
516500
)
517501

518502
_record_token_usage(span, response)
519-
self._exit_span(span_data, run_id)
503+
self._exit_span(span, run_id)
520504

521505
def on_llm_end(
522506
self: "SentryLangchainCallback",
@@ -530,8 +514,7 @@ def on_llm_end(
530514
if not run_id or run_id not in self.span_map:
531515
return
532516

533-
span_data = self.span_map[run_id]
534-
span = span_data.span
517+
span = self.span_map[run_id]
535518

536519
try:
537520
generation = response.generations[0][0]
@@ -579,7 +562,7 @@ def on_llm_end(
579562
)
580563

581564
_record_token_usage(span, response)
582-
self._exit_span(span_data, run_id)
565+
self._exit_span(span, run_id)
583566

584567
def on_llm_error(
585568
self: "SentryLangchainCallback",
@@ -612,15 +595,14 @@ def on_agent_finish(
612595
if not run_id or run_id not in self.span_map:
613596
return
614597

615-
span_data = self.span_map[run_id]
616-
span = span_data.span
598+
span = self.span_map[run_id]
617599

618600
if should_send_default_pii() and self.include_prompts:
619601
set_data_normalized(
620602
span, SPANDATA.GEN_AI_RESPONSE_TEXT, finish.return_values.items()
621603
)
622604

623-
self._exit_span(span_data, run_id)
605+
self._exit_span(span, run_id)
624606

625607
def on_tool_start(
626608
self: "SentryLangchainCallback",
@@ -637,14 +619,13 @@ def on_tool_start(
637619

638620
tool_name = serialized.get("name") or kwargs.get("name") or ""
639621

640-
watched_span = self._create_span(
622+
span = self._create_span(
641623
run_id,
642624
kwargs.get("parent_run_id"),
643625
op=OP.GEN_AI_EXECUTE_TOOL,
644626
name=f"execute_tool {tool_name}".strip(),
645627
origin=LangchainIntegration.origin,
646628
)
647-
span = watched_span.span
648629

649630
span.set_data(SPANDATA.GEN_AI_OPERATION_NAME, "execute_tool")
650631
span.set_data(SPANDATA.GEN_AI_TOOL_NAME, tool_name)
@@ -681,13 +662,12 @@ def on_tool_end(
681662
if not run_id or run_id not in self.span_map:
682663
return
683664

684-
span_data = self.span_map[run_id]
685-
span = span_data.span
665+
span = self.span_map[run_id]
686666

687667
if should_send_default_pii() and self.include_prompts:
688668
set_data_normalized(span, SPANDATA.GEN_AI_TOOL_OUTPUT, output)
689669

690-
self._exit_span(span_data, run_id)
670+
self._exit_span(span, run_id)
691671

692672
def on_tool_error(
693673
self,

0 commit comments

Comments
 (0)