Hi, Is it possible to add spans to an existing trace after the trace has already been completed and logged? I鈥檓 working on an application where some of the processing happens much later, and those details may only become available afterwards (sometimes after a day, sometimes even a week later).
No, Phoenix does not support adding spans to an existing trace after it has been completed and logged. Once a trace is finalized and its root span is submitted, the trace and its spans become immutable; new spans cannot be appended to that trace at a later time. This is a limitation of both Phoenix and the underlying OpenTelemetry standard, which treats spans as immutable after completion and does not allow updating or extending traces post-hoc. Any additional processing or details that occur later would need to be logged as part of a new trace or handled via annotations or metadata, but not as new spans within the original trace context. For more, see the discussion in this Slack thread and the explanation of span immutability in Phoenix documentation.Would you like more detail or suggestions for possible workarounds?Sources: - Slack thread: span/trace immutability - Phoenix documentation
馃挕聽Hint: Mention RunLLM in the thread for followups.
Is it possible to add spans to an existing trace
are you referring to modifying the content of an existing span to add or change attributes, or simply sending more (new) spans that have the same trace_id?
I was asking about sending new spans that have the same trace_id. Also, are we able to add attributes to a span after it has been created?
currently we don鈥檛 support updates on existing spans, but you can send in new spans any time
So if we just pass the trace headers to a service, it should be able to add spans to that trace anytime after?
you can try something like this
from secrets import token_hex
from phoenix.client import Client
from datetime import datetime, timezone
trace_id = "acbd7bfd4edc9e0118d0ba94bbbfd380"
parent_span_id = "6fe275bedcd32539"
client = Client()
client.spans.log_spans(
project_identifier="default",
spans=[{
"name": "my-span",
"context": {"trace_id": trace_id, "span_id": token_hex(8)},
"parent_id": parent_span_id,
"span_kind": "CHAIN",
"start_time": datetime.now(timezone.utc).isoformat(),
"end_time": datetime.now(timezone.utc).isoformat(),
"status_code": "OK",
"attributes": {
"xyz": "123",
},
}],
)