Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Guardrails ai Guardrails Runner Tracing

From Leeroopedia
Knowledge Sources
Domains Telemetry, OpenTelemetry, Observability
Last Updated 2026-02-14 00:00 GMT

Overview

The Runner Tracing module provides OpenTelemetry instrumentation decorators for tracing the Runner's step and call operations, supporting synchronous, asynchronous, and streaming execution modes.

Description

This module implements two categories of tracing instrumentation for the Guardrails runner:

Step Instrumentation

Step-level tracing wraps individual validation iterations (steps) within a Guard execution. Four decorator variants are provided:

  • trace_step -- Wraps a synchronous step function. Creates an OpenTelemetry span named "step", sets attributes including guardrails version, guard name, step index, serialized inputs, and serialized outputs. On error, sets the span status to ERROR.
  • trace_async_step -- The async equivalent of trace_step, for use with async step functions.
  • trace_stream_step -- Wraps a synchronous generator (streaming step). Yields each ValidationOutcome item while maintaining the tracing span context across the entire generator lifecycle. Captures the final iteration for span attributes in the finally block.
  • trace_async_stream_step -- The async generator equivalent of trace_stream_step, yielding ValidationOutcome items from an async iterator.

Call Instrumentation

Call-level tracing wraps individual LLM API calls made within a step:

  • trace_call -- Wraps a synchronous LLM call function. Creates a span named "call", serializes inputs and outputs (with redaction of sensitive keys), and handles streaming responses by deferring attribute logging.
  • trace_async_call -- The async equivalent of trace_call.

Common Behavior

All decorators check settings.disable_tracing before creating spans. When tracing is disabled, the wrapped function executes directly without instrumentation overhead. When the optional openinference library is available, spans are annotated with SpanAttributes.OPENINFERENCE_SPAN_KIND = "GUARDRAIL".

Input serialization applies redaction to sensitive keys via the recursive_key_operation utility.

Usage

These decorators are applied internally to the Runner's step and call methods. They are not typically used directly by end users but can be leveraged when building custom runner implementations that need OpenTelemetry observability.

Code Reference

Source Location

  • Repository: Guardrails
  • File: guardrails/telemetry/runner_tracing.py
  • Lines: 1-338

Signature

# Step instrumentation
def add_step_attributes(
    step_span: Span, response: Optional[Iteration], *args, **kwargs
) -> None: ...

def trace_step(fn: Callable[..., Iteration]) -> Callable[..., Iteration]: ...

def trace_stream_step(
    fn: Callable[..., Iterator[ValidationOutcome[OT]]]
) -> Callable[..., Iterator[ValidationOutcome[OT]]]: ...

def trace_async_step(
    fn: Callable[..., Awaitable[Iteration]]
) -> Callable[..., Awaitable[Iteration]]: ...

def trace_async_stream_step(
    fn: Callable[..., AsyncIterator[ValidationOutcome[OT]]]
) -> Callable[..., AsyncIterator[ValidationOutcome[OT]]]: ...

# Call instrumentation
def add_call_attributes(
    call_span: Span, response: Optional[LLMResponse], *args, **kwargs
) -> None: ...

def trace_call(fn: Callable[..., LLMResponse]) -> Callable[..., LLMResponse]: ...

def trace_async_call(
    fn: Callable[..., Awaitable[LLMResponse]]
) -> Callable[..., Awaitable[LLMResponse]]: ...

Import

from guardrails.telemetry.runner_tracing import trace_step, trace_call
from guardrails.telemetry.runner_tracing import trace_async_step, trace_async_call
from guardrails.telemetry.runner_tracing import trace_stream_step, trace_async_stream_step

I/O Contract

Inputs

trace_step / trace_async_step

Name Type Required Description
fn Callable[..., Iteration] or Callable[..., Awaitable[Iteration]] Yes The step function to instrument. Receives runner arguments including the step index.

trace_call / trace_async_call

Name Type Required Description
fn Callable[..., LLMResponse] or Callable[..., Awaitable[LLMResponse]] Yes The LLM call function to instrument.

trace_stream_step / trace_async_stream_step

Name Type Required Description
fn Callable[..., Iterator[ValidationOutcome]] or Callable[..., AsyncIterator[ValidationOutcome]] Yes The streaming step generator function to instrument.

Outputs

Decorator Return Type Description
trace_step Callable[..., Iteration] Wrapped function that creates a "step" span and returns the Iteration result.
trace_async_step Callable[..., Awaitable[Iteration]] Async wrapped function with "step" span.
trace_stream_step Callable[..., Iterator[ValidationOutcome]] Wrapped generator with span spanning the full iteration lifecycle.
trace_async_stream_step Callable[..., AsyncIterator[ValidationOutcome]] Async wrapped generator with span spanning the full iteration lifecycle.
trace_call Callable[..., LLMResponse] Wrapped function that creates a "call" span and returns the LLMResponse.
trace_async_call Callable[..., Awaitable[LLMResponse]] Async wrapped function with "call" span.

Span Attributes

The following OpenTelemetry span attributes are set by the tracing functions:

Attribute Value Scope
guardrails.version GUARDRAILS_VERSION Step and Call
type "guardrails/guard/step" or "guardrails/guard/step/call" Step or Call
guard.name Name of the current guard Step and Call
step.index The iteration index Step only
input.mime_type "application/json" Step and Call
input.value JSON-serialized and redacted input arguments Step and Call
output.mime_type "application/json" Step and Call (when output exists)
output.value JSON-serialized output Step and Call (when output exists)
SpanAttributes.OPENINFERENCE_SPAN_KIND "GUARDRAIL" Step (when openinference is available)

Usage Examples

from guardrails.telemetry.runner_tracing import trace_step, trace_call

# Decorating a synchronous step function
@trace_step
def my_step(runner, index, *args, **kwargs):
    # Perform validation iteration
    return iteration_result

# Decorating an LLM call function
@trace_call
def call_llm(prompt, model, **kwargs):
    # Make LLM API call
    return llm_response

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment