Instrumentation()

Overview

All Respan instrumentation plugins implement a simple protocol with name, activate(), and deactivate(). This lets you build plugins for any vendor SDK and have them work with Respan().

Protocol

1from respan import Instrumentation
2
3class Instrumentation(Protocol):
4 name: str
5
6 def activate(self) -> None:
7 """Start intercepting spans and injecting them into the OTEL pipeline."""
8 ...
9
10 def deactivate(self) -> None:
11 """Stop intercepting spans and clean up resources."""
12 ...
Attribute/MethodDescription
nameUnique identifier for the plugin (e.g. "openai-agents", "openai").
activate()Called by Respan.__init__(). Registers hooks/processors with the vendor SDK.
deactivate()Called by Respan.shutdown(). Cleans up hooks/processors.

Building a custom plugin

A plugin typically:

  1. Registers a hook or processor with the vendor SDK in activate().
  2. On each SDK event, converts it to a ReadableSpan using build_readable_span().
  3. Injects the span into the OTEL pipeline using inject_span().

Minimal example

1from respan import Respan
2from respan_tracing.utils.span_factory import build_readable_span, inject_span
3
4class MySDKInstrumentor:
5 name = "my-sdk"
6
7 def activate(self) -> None:
8 # Register a callback with the vendor SDK
9 import my_sdk
10 my_sdk.on_completion(self._on_completion)
11
12 def deactivate(self) -> None:
13 import my_sdk
14 my_sdk.remove_callback(self._on_completion)
15
16 def _on_completion(self, event):
17 span = build_readable_span(
18 name=f"my-sdk.completion",
19 trace_id=event.trace_id,
20 attributes={
21 "llm.request.type": "chat",
22 "gen_ai.request.model": event.model,
23 "gen_ai.usage.prompt_tokens": event.input_tokens,
24 "gen_ai.usage.completion_tokens": event.output_tokens,
25 "traceloop.span.kind": "task",
26 "traceloop.entity.name": "completion",
27 },
28 )
29 inject_span(span)
30
31# Use it
32respan = Respan(
33 api_key="your-api-key",
34 instrumentations=[MySDKInstrumentor()],
35)

Key functions

FunctionModuleDescription
build_readable_span()respan_tracing.utils.span_factoryCreates a ReadableSpan with proper trace/span IDs, timestamps, and attributes. Automatically reads propagated attributes from the current context.
inject_span()respan_tracing.utils.span_factoryInjects a ReadableSpan into the global OTEL processor chain for export.
read_propagated_attributes()respan_tracing.utils.span_factoryReads the current propagate_attributes() context. Useful if you need to inspect attributes before building the span.

Required attributes

For spans to be processed and displayed correctly by the Respan backend:

AttributeRequiredDescription
traceloop.span.kindYesOne of "workflow", "agent", "task", "tool".
traceloop.entity.nameYesHuman-readable span name.
llm.request.typeFor LLM spansSet to "chat" to trigger prompt/completion parsing.
gen_ai.request.modelFor LLM spansModel name.

Existing plugins

PluginPackageSDK
OpenAI Agents SDKrespan-instrumentation-openai-agentsopenai-agents
OpenAIrespan-instrumentation-openaiopenai