Agent run traces are viewable at https://platform.openai.com/traces in the OpenAI Dashboard after a run completes.[1] set_tracing_disabled(disabled) in src/agents/tracing/__init__.py globally enables or disables tracing by calling get_trace_provider().set_disabled(disabled).[2] trace_include_sensitive_data defaults to True but can be overridden by setting the OPENAI_AGENTS_TRACE_INCLUDE_SENSITIVE_DATA environment variable to 0, false, no, or off.[3]
add_trace_processor(span_processor) in src/agents/tracing/__init__.py registers an additional TracingProcessor with the global trace provider; it calls get_trace_provider().register_processor(span_processor) and is additive (does not replace existing processors).[2] set_trace_processors(processors) in src/agents/tracing/__init__.py replaces the entire current list of trace processors on the global provider; use add_trace_processor instead to append without clearing existing ones.[2] flush_traces() in src/agents/tracing/__init__.py forces immediate export of buffered traces; the default BatchTraceProcessor exports periodically in the background, so flush_traces() is needed when a worker or request handler needs traces visible immediately after a unit of work finishes.[2] set_tracing_export_api_key(api_key) in src/agents/tracing/__init__.py sets the OpenAI API key used by the default backend exporter, calling default_exporter().set_api_key(api_key).[2] BatchTraceProcessor in src/agents/tracing/processors.py collects spans in memory and exports them to a SpanExporter (such as BackendSpanExporter) in periodic background batches rather than one at a time, reducing export overhead.
The Span context-manager protocol in src/agents/tracing/spans.py calls start(mark_as_current=True) in __enter__ and finish(reset_current=True) in __exit__, providing automatic span lifecycle management; using context managers is the documented approach for reliable start/finish.[4] Span.start(mark_as_current=True) in src/agents/tracing/spans.py pushes the span as the context-var current span; finish(reset_current=True) pops it. The mark_as_current and reset_current flags are separate parameters, both defaulting to False.[4] SpanImpl.start() in src/agents/tracing/spans.py calls TracingProcessor.on_span_start(self) and records an ISO timestamp; calling it a second time only logs a warning and returns without effect.[4] SpanImpl.finish() in src/agents/tracing/spans.py calls TracingProcessor.on_span_end(self) and records an ISO timestamp; calling it a second time only logs a warning and returns without effect.[4] Span.__exit__ in src/agents/tracing/spans.py detects GeneratorExit and delegates to _finish_on_generator_exit instead of the normal finish(reset_current=True) path, to handle abandoned async generators safely.[4] _finish_on_generator_exit in src/agents/tracing/spans.py silently swallows ValueError from Scope.reset_current_span because an abandoned async generator may be finalized from a different task whose context never set the token — raising would add a crash on top of an already-unwinding generator.[4]
The Span abstract base class in src/agents/tracing/spans.py exposes started_at and ended_at as ISO-format timestamp strings (or None if not yet started/finished), and tracing_api_key for export authentication.[4] SpanImpl in src/agents/tracing/spans.py accepts an optional trace_metadata dict stored and exposed via the inherited trace_metadata property, enabling trace-level metadata to propagate to individual spans.[4] When span_id is not provided to SpanImpl.__init__ in src/agents/tracing/spans.py, a new span ID is auto-generated via util.gen_span_id().[4] Both NoOpSpan and SpanImpl in src/agents/tracing/spans.py manage the current-span context via Scope.set_current_span (on start) and Scope.reset_current_span (on finish), using a stored _prev_span_token.[4] SpanError in src/agents/tracing/spans.py is a TypedDict with a message string and an optional data dict for attaching arbitrary error context to a span. The canonical pattern for recording errors is to call span.set_error({"message": str(e), "data": {...}}) inside an except block, then re-raise.[4] NoOpSpan in src/agents/tracing/spans.py is a no-op Span implementation used when tracing is disabled; export() returns None, error is always None, and trace_id/span_id both return the literal string "no-op".[4]
BackendSpanExporter in src/agents/tracing/processors.py posts traces to https://api.openai.com/v1/traces/ingest by default (the endpoint constructor parameter), and adds the OpenAI-Beta: traces=v1 header to every export request.[5] BackendSpanExporter resolves the API key at first access from os.environ["OPENAI_API_KEY"] if not set in the constructor (cached via @cached_property); calling set_api_key() clears the cache so the new value takes effect.[5] BackendSpanExporter.set_api_key() in src/agents/tracing/processors.py manually deletes the api_key entry from __dict__ to invalidate the @cached_property before storing the new key.[5] BackendSpanExporter in src/agents/tracing/processors.py reads the OpenAI organization from os.environ["OPENAI_ORG_ID"] and the project from os.environ["OPENAI_PROJECT_ID"] when those fields are not supplied to the constructor.[5] BackendSpanExporter skips exporting an entire group and logs a warning when no API key is resolvable for that group.[5] BackendSpanExporter._export_with_deadline in src/agents/tracing/processors.py groups items by their tracing_api_key and issues a separate HTTP POST per group, allowing multi-tenant exports in a single call.[5] BackendSpanExporter in src/agents/tracing/processors.py keeps a persistent httpx2.Client with a 60-second read timeout and a 5-second connect timeout, enabling connection pooling across export calls.[5] BackendSpanExporter in src/agents/tracing/processors.py defaults to max_retries=3, base_delay=1.0 second, and max_delay=30.0 seconds for exponential backoff on failed exports.[5] BackendSpanExporter in src/agents/tracing/processors.py treats HTTP 4xx responses as non-retryable and logs an error, while 5xx or unexpected codes are retried up to max_retries.[5] BackendSpanExporter in src/agents/tracing/processors.py applies exponential backoff with 10% jitter between retries: sleep_time = delay + random.uniform(0, 0.1 * delay), doubling delay each attempt up to max_delay.[5] BackendSpanExporter._sleep_before_retry in src/agents/tracing/processors.py interrupts its sleep early and returns False if the shutdown event fires, abandoning the remaining retries cleanly on shutdown.[5] BackendSpanExporter sanitizes payloads before sending to the OpenAI ingest endpoint: it truncates input/output fields to 100,000 bytes (with a ... [truncated] suffix) and drops the usage key from non-generation span types.[5] Sanitization in BackendSpanExporter (src/agents/tracing/processors.py) is only applied when the configured endpoint matches https://api.openai.com/v1/traces/ingest; custom endpoints receive the raw payload.[5]
ConsoleSpanExporter in src/agents/tracing/processors.py prints trace and span data to stdout, but redacts all content to a short notice string when either _debug.DONT_LOG_MODEL_DATA or _debug.DONT_LOG_TOOL_DATA is set.[5]
Sources