mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-09-23 19:30:45 +00:00
feat(telemetry): add execution UUID to telemetry spans
Enhance the `operation` function to include the execution UUID in span attributes, allowing for better tracking of execution contexts. If an execution UUID is present, it is added to the span attributes unless explicitly provided. Additionally, introduce tests to verify that the execution UUID is correctly stamped from the context and that explicit UUIDs are preserved. This improves traceability in telemetry data.
This commit is contained in:
@@ -21,6 +21,8 @@ from opentelemetry.trace import (
|
||||
TraceFlags,
|
||||
)
|
||||
|
||||
from crewai.execution import get_execution_uuid
|
||||
|
||||
|
||||
_TRACER_NAME = "crewai"
|
||||
|
||||
@@ -70,9 +72,14 @@ def operation(
|
||||
The active :class:`Span`. Callers may attach additional
|
||||
attributes or events to it as the operation progresses.
|
||||
"""
|
||||
attrs: dict[str, Any] = dict(attributes or {})
|
||||
execution_uuid = get_execution_uuid()
|
||||
if execution_uuid and "crewai.execution_uuid" not in attrs:
|
||||
attrs["crewai.execution_uuid"] = execution_uuid
|
||||
|
||||
with _tracer().start_as_current_span(
|
||||
name,
|
||||
attributes=attributes or {},
|
||||
attributes=attrs,
|
||||
links=links or [],
|
||||
record_exception=False,
|
||||
set_status_on_exception=False,
|
||||
@@ -85,6 +92,8 @@ def operation(
|
||||
span.record_exception(exc, escaped=True)
|
||||
span.set_status(Status(StatusCode.ERROR, f"{type(exc).__name__}: {exc}"))
|
||||
raise
|
||||
else:
|
||||
span.set_status(Status(StatusCode.OK))
|
||||
|
||||
|
||||
def follows_from(
|
||||
|
||||
@@ -210,7 +210,37 @@ class TestOperation:
|
||||
finished = span_exporter.get_finished_spans()
|
||||
assert [s.name for s in finished] == ["sample op"]
|
||||
assert finished[0].attributes["crewai.test.key"] == "value"
|
||||
assert finished[0].status.status_code == StatusCode.UNSET
|
||||
assert finished[0].status.status_code == StatusCode.OK
|
||||
|
||||
def test_stamps_execution_uuid_from_contextvar(
|
||||
self, span_exporter: InMemorySpanExporter
|
||||
) -> None:
|
||||
from crewai.execution import clear_execution_uuid, set_execution_uuid
|
||||
|
||||
token = set_execution_uuid("kickoff-uuid-1")
|
||||
try:
|
||||
with operation("sample op"):
|
||||
pass
|
||||
finally:
|
||||
clear_execution_uuid(token)
|
||||
|
||||
finished = span_exporter.get_finished_spans()
|
||||
assert finished[0].attributes["crewai.execution_uuid"] == "kickoff-uuid-1"
|
||||
|
||||
def test_leaves_explicit_execution_uuid_in_place(
|
||||
self, span_exporter: InMemorySpanExporter
|
||||
) -> None:
|
||||
from crewai.execution import clear_execution_uuid, set_execution_uuid
|
||||
|
||||
token = set_execution_uuid("contextvar-id")
|
||||
try:
|
||||
with operation("sample op", {"crewai.execution_uuid": "explicit-id"}):
|
||||
pass
|
||||
finally:
|
||||
clear_execution_uuid(token)
|
||||
|
||||
finished = span_exporter.get_finished_spans()
|
||||
assert finished[0].attributes["crewai.execution_uuid"] == "explicit-id"
|
||||
|
||||
def test_exception_marks_span_error(
|
||||
self, span_exporter: InMemorySpanExporter
|
||||
@@ -310,6 +340,7 @@ class TestHotPathSpans:
|
||||
]
|
||||
assert len(crew_spans) == 1
|
||||
assert crew_spans[0].attributes["crewai.crew.id"] == str(crew.id)
|
||||
assert crew_spans[0].attributes.get("crewai.execution_uuid")
|
||||
|
||||
def test_nested_spans_share_trace_id(
|
||||
self, span_exporter: InMemorySpanExporter
|
||||
|
||||
Reference in New Issue
Block a user