Rhesis
haystack_integrations.components.connectors.rhesis.rhesis_connector
RhesisConnector
Connects Haystack to Rhesis for OpenTelemetry-based tracing of pipelines.
Add this component to a pipeline without connecting it to other components. It enables tracing for all pipeline operations when Haystack tracing is active.
Environment Configuration:
RHESIS_API_KEY: Required API key for trace ingestion.RHESIS_BASE_URL: Backend URL (defaulthttp://localhost:8080for local development).RHESIS_PROJECT_ID: Optional project identifier (resolved from the API key when omitted).RHESIS_ENVIRONMENT: Deployment environment label (defaultdevelopment).RHESIS_FRONTEND_URL: Optional frontend URL used to buildtrace_urldeep links.HAYSTACK_CONTENT_TRACING_ENABLED: Must be"true"before importing Haystack to capture input/output on spans.HAYSTACK_RHESIS_ENFORCE_FLUSH: When"true"(default), exports once per pipeline run, as the root span closes. Set to"false"to leave exporting to the batch processor and flush on shutdown instead.
Example shutdown flush for FastAPI:
from haystack.tracing import tracer
@app.on_event("shutdown")
async def shutdown_event():
tracer.actual_tracer.flush()
init
__init__(
name: str,
api_key: Secret | None = Secret.from_env_var("RHESIS_API_KEY"),
base_url: str | None = None,
project_id: str | None = None,
environment: str | None = None,
frontend_url: str | None = None,
span_handler: SpanHandler | None = None,
) -> None
Initialize the RhesisConnector component.
Parameters:
- name (
str) – Trace name shown in the Rhesis UI. - api_key (
Secret | None) – Rhesis API key. Defaults toRHESIS_API_KEY. - base_url (
str | None) – Rhesis backend base URL. Defaults toRHESIS_BASE_URLorhttp://localhost:8080. - project_id (
str | None) – Rhesis project ID. Defaults toRHESIS_PROJECT_ID. - environment (
str | None) – Environment label. Defaults toRHESIS_ENVIRONMENTordevelopment. - frontend_url (
str | None) – Frontend base URL fortrace_url. Defaults toRHESIS_FRONTEND_URL. - span_handler (
SpanHandler | None) – Optional custom span handler. Uses :class:DefaultSpanHandlerwhen omitted.
Raises:
ValueError– If no API key resolves. A component the user explicitly added to a pipeline should say so rather than silently trace nothing — but it does meanPipeline.from_dicton a YAML containing this component needs credentials present. :class:~haystack_integrations.tracing.rhesis.RhesisTracingdeliberately does the opposite and degrades to a no-op, because there the caller did not put tracing in the data path.
run
Run the connector and return trace metadata.
The context applies to the pipeline run that invoked this component and no other. The
ContextVar it is written to is set by RhesisTracer.trace when the run's root span opens
and restored when that span closes, so this write lands inside that scope and cannot outlive
the run — which is why the context is only honoured when a root span is open. Outside one
there is nothing to scope it to and nothing to stamp it on, so it is ignored rather than left
behind for the next caller to inherit. To attach metadata to work that is not a pipeline run
— a standalone Agent, say — wrap the call in
:func:~haystack_integrations.tracing.rhesis.rhesis_invocation_context instead, which scopes
the value to its own block.
Parameters:
- invocation_context (
dict[str, Any] | None) – Optional key-value metadata attached to the root trace (session, test run identifiers, tags, etc.).
Returns:
dict[str, str]– Dictionary withname,trace_url, andtrace_id.
to_dict
Serialize this component to a dictionary.
Records the arguments as they were passed, not as they were resolved: anything left to the
environment stays None so that deserializing on another machine resolves it there. This
mirrors how Secret.from_env_var serializes a reference rather than the secret's value.
from_dict
Deserialize this component from a dictionary.
haystack_integrations.tracing.rhesis.conversation
Conversation-aware tracing for applications that drive Haystack from their own loop.
ConversationTurn
A single conversation turn, yielded by :meth:RhesisTracing.turn.
Assign :attr:output with the reply the user actually sees. Only the application knows
what that is — it may be a tool result or a value held in agent state rather than the last
assistant message — so it cannot be inferred from the span tree.
span
The underlying OTel span, or None when tracing is disabled.
output
The reply recorded for this turn.
RhesisTracing
Enable Rhesis tracing for an application that runs Haystack from its own loop.
:class:RhesisConnector covers the common case: add it to a pipeline and every run is
traced. An application that owns its loop — a chat REPL, a batch script, a server handling
one turn per request — needs two things a component inside the pipeline cannot provide:
tracing switched on without a pipeline to attach to, and a span wrapping a whole pipeline
run so a conversation turn has a root of its own.
Without that root span, the Haystack pipeline span claims the turn and reports the serialized pipeline input and output as the conversation text.
HAYSTACK_CONTENT_TRACING_ENABLED must still be set to "true" before Haystack is
imported, exactly as when using the connector.
Usage example
import os
os.environ["HAYSTACK_CONTENT_TRACING_ENABLED"] = "true"
from haystack_integrations.tracing.rhesis import RhesisTracing
tracing = RhesisTracing("My Assistant")
tracing.start_conversation("conversation-1")
for message in ["Hello", "Tell me more"]:
with tracing.turn(message) as turn:
result = pipeline.run(...)
turn.output = result["llm"]["replies"][0].text
tracing.flush()
init
__init__(
name: str,
*,
enabled: bool = True,
turn_span_name: str = DEFAULT_TURN_SPAN_NAME,
**connector_kwargs: Any
) -> None
Enable tracing, or fall back to a no-op when Rhesis is not configured.
Construction never raises on a missing or rejected configuration: an application should
run untraced rather than fail to start. Check :attr:enabled to report it.
This is the opposite of :class:~haystack_integrations.components.connectors.rhesis.RhesisConnector,
which raises when no API key resolves, and deliberately so. The connector is a component the
user put in a pipeline; failing loudly there is the honest signal that the thing they wired
up will not do its job. Here tracing wraps an application's own loop and is not in its data
path, so the same failure should cost the application nothing.
Parameters:
- name (
str) – Trace name shown in the Rhesis UI. - enabled (
bool) – Set toFalseto build a no-op instance, so an application can gate tracing on its own policy without branching around every call. - turn_span_name (
str) – Span name for each conversation turn root. - connector_kwargs (
Any) – Forwarded to :class:RhesisConnector(api_key,base_url,project_id,environment,frontend_url,span_handler).
enabled
Whether tracing was successfully enabled.
start_conversation
Group the turns that follow into one conversation, sharing one trace.
Calling this again starts a new conversation: the next turn opens a new trace and later turns join it.
Parameters:
- conversation_id (
str) – Identifier grouping the turns, shown as the conversation in Rhesis. - invocation_context (
Any) – Extra metadata for the root span, as :meth:RhesisConnector.runaccepts (test run identifiers, tags, …).
turn
Open the root span for one conversation turn.
Run the turn's work inside the block and assign the reply to
:attr:ConversationTurn.output. Every turn after the first joins the first one's trace,
so a conversation reads as one trace rather than one per exchange.
Yields an inert turn when tracing is disabled, so callers need no branching.
Parameters:
- user_input (
str) – The user's message, recorded as the turn's conversation input.
flush
Flush pending spans. Call before exit; batched spans are otherwise lost.
haystack_integrations.tracing.rhesis.tracer
Rhesis tracing bridge for Haystack.
Set HAYSTACK_CONTENT_TRACING_ENABLED=true before importing Haystack to capture
input/output content on spans.
rhesis_invocation_context
rhesis_invocation_context(
invocation_context: dict[str, Any] | None = None,
) -> Iterator[None]
Attach Rhesis session/test metadata for the current async task or thread.
RhesisTelemetry
Thin wrapper around the OTel provider used by the Haystack integration.
flush
Flush pending spans to the Rhesis backend.
resolve_frontend_url
Resolve the Rhesis frontend base URL for trace deep links.
Only the two well-known deployments are derived from base_url. Any other backend returns an
empty string — and therefore an empty trace_url — unless RHESIS_FRONTEND_URL is set.
Parameters:
- base_url (
str) – The Rhesis backend base URL. - frontend_url (
str | None) – An explicit frontend origin, which always wins when given.
Returns:
str– The frontend origin without a trailing slash, or""when it cannot be derived.
build_trace_url
build_trace_url(
frontend_url: str, trace_id: str, project_id: str | None
) -> str
Build a frontend deep link for the given trace.
RhesisSpan
Bases: Span
Bridge between Haystack's span API and OpenTelemetry spans for Rhesis.
set_tag
Set a generic tag for this span.
set_content_tag
Set a content-specific tag for this span when content tracing is enabled.
raw_span
Return the underlying OpenTelemetry span instance.
close
End the underlying OpenTelemetry span.
Parameters:
- exc_info (
tuple[Any, Any, Any] | None) – Thesys.exc_info()triple when the span is closing because of an exception, so the context manager sees it;Noneon the success path.
get_data
Return the raw Haystack tag data collected for this span.
get_correlation_data_for_logs
Return trace and span identifiers for log correlation.
set_tags
Set multiple tags on this span.
SpanContext
Context for creating spans in Rhesis.
SpanHandler
Bases: ABC
Extension point for customizing Rhesis span creation and enrichment.
init_tracer
Initialize with the Rhesis telemetry wrapper.
create_span
Create a span of appropriate type based on the context.
handle
Process a span after component execution.
from_dict
Deserialize a SpanHandler from a dictionary.
to_dict
Serialize this SpanHandler to a dictionary.
DefaultSpanHandler
Bases: SpanHandler
Default Rhesis tracing behavior for Haystack pipelines.
create_span
Create a Rhesis span based on the given Haystack context.
handle
Process and enrich a span after component execution.
RhesisTracer
Bases: Tracer
Haystack tracer implementation that exports spans to Rhesis via OpenTelemetry.
init
__init__(
telemetry: RhesisTelemetry,
name: str = "Haystack",
span_handler: SpanHandler | None = None,
) -> None
Initialize a RhesisTracer instance.
Parameters:
- telemetry (
RhesisTelemetry) – Configured Rhesis OpenTelemetry telemetry wrapper. - name (
str) – Trace name shown in the Rhesis UI. - span_handler (
SpanHandler | None) – Custom handler for span creation and enrichment.
telemetry
The Rhesis OTel provider and tracer backing this tracer.
Public because the provider is private to this tracer: it is not installed as the
OpenTelemetry global, so anything that needs to open a span destined for Rhesis — the
conversation turn spans in :class:~haystack_integrations.tracing.rhesis.RhesisTracing, or a
custom :class:SpanHandler — has to reach it through here rather than through
trace.get_tracer().
trace
trace(
operation_name: str,
tags: dict[str, Any] | None = None,
parent_span: Span | None = None,
) -> Iterator[Span]
Create and manage a tracing span as a context manager.
flush
Flush all pending spans to Rhesis.
current_span
Return the current active span.
get_trace_url
Return the frontend URL for the current trace, when available.
get_trace_id
Return the trace ID of the root span currently open in this context.