Implementation:Guardrails ai Guardrails Guard Tracing
| Knowledge Sources | |
|---|---|
| Domains | Telemetry, Observability, LLM Integration |
| Last Updated | 2026-02-14 00:00 GMT |
Overview
The Guard Tracing module instruments guard execution with OpenTelemetry spans, capturing validation outcomes, token consumption, reask counts, and LLM call metadata for both synchronous and asynchronous guard invocations.
Description
This module provides the primary telemetry instrumentation for Guardrails guard execution. It creates OpenTelemetry spans named "guard" around guard execution functions and enriches them with detailed attributes:
add_guard_attributes extracts the last iteration's input messages (system and user), traces the operation via the open inference module, and sets span attributes for validation pass/fail status, execution ID, token consumption, number of reasks, and number of LLM calls.
trace_guard_execution wraps synchronous guard execution. It creates a span with the guard name and Guardrails version, invokes the execution function, and handles both single-result and streaming cases. For streaming results, it delegates to trace_stream_guard, which iterates through the stream, creating linked spans when the original span stops recording.
trace_async_guard_execution provides the same instrumentation for async guard execution, handling AsyncIterator results via trace_async_stream_guard and awaitable results. Both sync and async variants set error status on spans when exceptions occur.
The module integrates with the OpenInference semantic conventions library (optional) to set OPENINFERENCE_SPAN_KIND to "GUARDRAIL" on all spans. When settings.disable_tracing is True, all tracing is bypassed.
Usage
Use this module when you need to instrument guard execution with OpenTelemetry tracing. The trace_guard_execution and trace_async_guard_execution functions are called internally by the Guard and AsyncGuard classes. They should be invoked by passing the guard name, history stack, and execution function along with its arguments.
Code Reference
Source Location
- Repository: Guardrails
- File:
guardrails/telemetry/guard_tracing.py
Signature
def add_guard_attributes(
guard_span: Span,
history: Stack[Call],
resp: ValidationOutcome,
)
def trace_stream_guard(
guard_span: Span,
result: Iterator[ValidationOutcome[OT]],
history: Stack[Call],
) -> Iterator[ValidationOutcome[OT]]
def trace_guard_execution(
guard_name: str,
history: Stack[Call],
_execute_fn: Callable[
..., Union[ValidationOutcome[OT], Iterator[ValidationOutcome[OT]]]
],
*args,
**kwargs,
) -> Union[ValidationOutcome[OT], Iterator[ValidationOutcome[OT]]]
async def trace_async_stream_guard(
guard_span: Span,
result: AsyncIterator[ValidationOutcome[OT]],
history: Stack[Call],
) -> AsyncIterator[ValidationOutcome[OT]]
async def trace_async_guard_execution(
guard_name: str,
history: Stack[Call],
_execute_fn: Callable[
...,
Coroutine[
Any, Any,
Union[
ValidationOutcome[OT],
Awaitable[ValidationOutcome[OT]],
AsyncIterator[ValidationOutcome[OT]],
],
],
],
*args,
**kwargs,
) -> Union[
ValidationOutcome[OT],
Awaitable[ValidationOutcome[OT]],
AsyncIterator[ValidationOutcome[OT]],
]
Import
from guardrails.telemetry.guard_tracing import (
trace_guard_execution,
trace_async_guard_execution,
add_guard_attributes,
)
I/O Contract
trace_guard_execution
| Parameter | Type | Description |
|---|---|---|
guard_name |
str |
The name of the guard being executed |
history |
Stack[Call] |
The guard's call history stack |
_execute_fn |
Callable |
The guard execution function to instrument |
*args |
Any |
Positional arguments passed to the execution function |
**kwargs |
Any |
Keyword arguments passed to the execution function |
| Returns | Type | Description |
|---|---|---|
| Result | Union[ValidationOutcome[OT], Iterator[ValidationOutcome[OT]]] |
The guard execution result, either a single outcome or a streaming iterator |
trace_async_guard_execution
| Parameter | Type | Description |
|---|---|---|
guard_name |
str |
The name of the guard being executed |
history |
Stack[Call] |
The guard's call history stack |
_execute_fn |
Callable |
The async guard execution function to instrument |
*args |
Any |
Positional arguments passed to the execution function |
**kwargs |
Any |
Keyword arguments passed to the execution function |
| Returns | Type | Description |
|---|---|---|
| Result | Union[ValidationOutcome[OT], Awaitable[ValidationOutcome[OT]], AsyncIterator[ValidationOutcome[OT]]] |
The async guard execution result |
Span Attributes Set
| Attribute | Type | Description |
|---|---|---|
guardrails.version |
str |
The Guardrails library version |
type |
str |
Always "guardrails/guard"
|
guard.name |
str |
The guard name |
validation_passed |
bool |
Whether validation passed |
execution_id |
str |
The execution ID from the call history |
token_consumption |
int |
Total tokens consumed |
number_of_reasks |
int |
Number of reask iterations |
number_of_llm_calls |
int |
Number of LLM calls (reasks + 1) |
Usage Examples
from guardrails.telemetry.guard_tracing import trace_guard_execution
from guardrails.classes.generic.stack import Stack
# Instrument a synchronous guard execution
def my_execute_fn(*args, **kwargs):
# Guard execution logic
return validation_outcome
result = trace_guard_execution(
guard_name="my_guard",
history=guard_history_stack,
_execute_fn=my_execute_fn,
messages=[{"role": "user", "content": "Hello"}],
)
# The span will automatically capture:
# - guardrails.version
# - guard.name = "my_guard"
# - validation_passed = True/False
# - token_consumption
# - number_of_reasks
# - number_of_llm_calls