OpenTelemetry integration

Capture any OpenTelemetry-instrumented AI agent with SteelSpine. Zero code changes. 50+ frameworks supported via standard OTLP/HTTP.

For non-technical readers: OpenTelemetry (OTel) is the industry-standard way to record what software does as it runs. Most modern AI agent frameworks have OpenTelemetry built in. SteelSpine includes a receiver that converts OpenTelemetry traces into signed audit events. Once configured, every agent action is captured into a tamper-evident chain that a regulator can verify independently. The dev team enables it once; the audit trail accumulates automatically.

Why OpenTelemetry matters here

OpenTelemetry is a vendor-neutral observability standard maintained by the Cloud Native Computing Foundation. As of 2026, every major AI agent framework supports it natively or via auto-instrumentation:

Because they all speak the same protocol, integrating any of them with SteelSpine is the same three-step process. Once the receiver is running, pointing a new framework at it is one environment variable.

The 3-step integration

Step 1: Start the SteelSpine OTEL receiver

steelspine otel-receiver --port 4318 --project <your-agent-name>

The receiver listens on port 4318 (the standard OTLP/HTTP port) and accepts traces over OTLP/HTTP with JSON encoding. It runs in the foreground; for production deployments, configure as a systemd service.

Useful flags:

FlagPurpose
--port NListen port (default 4318)
--run-id IDTag all events with a specific run ID
--project NAMERoute events to a project namespace (workspace isolation)
--verbosePrint each span as it arrives (useful for verifying capture)
--onceExit after one batch (useful for testing)

Step 2: Point your agent at the receiver

Set these two environment variables in the shell where your agent runs:

export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
export OTEL_EXPORTER_OTLP_PROTOCOL=http/json

The http/json protocol setting is required. SteelSpine's receiver currently accepts OTLP/HTTP with JSON encoding. Without setting the protocol to http/json, frameworks may default to protobuf which is not yet supported.

Step 3: Run your agent as normal

No code changes. Every span emitted by your agent gets captured into SteelSpine's signed event chain.

# LangChain agent
python3 my_langchain_agent.py

# CrewAI workflow
python3 my_crew.py

# Custom Python agent with OpenTelemetry SDK
python3 my_custom_agent.py

Verifying it's working

Health endpoint

curl -s http://localhost:4318/health

Returns:

{
  "status": "ok",
  "run_id": "otel_20260524_143000",
  "events_file": "/home/user/.prime/projects/my-agent/runs/otel_20260524_143000/events.jsonl",
  "events_received": 47
}

Verbose mode (live confirmation)

steelspine otel-receiver --port 4318 --verbose

Each captured span prints to stdout as it arrives:

  +1 event(s) from 1 span(s)  14:30:15
  +1 event(s) from 1 span(s)  14:30:16
  +1 event(s) from 1 span(s)  14:30:17

List captured runs

steelspine run list

Generate compliance report

steelspine verify-run --compliance-html > agent_audit.html

Opens in any browser. Shows event timeline, integrity status, regulatory tag block.

Framework-specific configuration

LangChain (Python)

LangChain auto-instruments when OpenTelemetry environment variables are set:

pip install opentelemetry-distro opentelemetry-exporter-otlp
opentelemetry-bootstrap --action=install

export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
export OTEL_EXPORTER_OTLP_PROTOCOL=http/json
export OTEL_SERVICE_NAME=my-langchain-agent

opentelemetry-instrument python3 my_langchain_agent.py

Or use SteelSpine's native LangChain handler (no auto-instrumentation required):

pip install steelspine-langchain
# Then in your code:
from steelspine_langchain import SteelSpineCallbackHandler
handler = SteelSpineCallbackHandler()
llm = ChatOpenAI(callbacks=[handler])

LlamaIndex

pip install llama-index-instrumentation-opentelemetry

# In your code:
from llama_index.core import set_global_handler
set_global_handler("opentelemetry")

# Then run with env vars set as above

CrewAI

pip install opentelemetry-instrumentation-langchain
opentelemetry-bootstrap --action=install

export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
export OTEL_EXPORTER_OTLP_PROTOCOL=http/json
opentelemetry-instrument python3 my_crew.py

Custom Python agent

pip install opentelemetry-sdk opentelemetry-exporter-otlp-proto-http

# In your code:
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter

trace.set_tracer_provider(TracerProvider())
trace.get_tracer_provider().add_span_processor(
    BatchSpanProcessor(OTLPSpanExporter(endpoint="http://localhost:4318/v1/traces"))
)

tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("my_operation"):
    # your agent code
    pass

Node.js / TypeScript agent

npm install @opentelemetry/sdk-node @opentelemetry/exporter-trace-otlp-http

# Set env vars
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
OTEL_EXPORTER_OTLP_PROTOCOL=http/json

node --require @opentelemetry/auto-instrumentations-node/register my_agent.js

How OTel spans map to SteelSpine events

SteelSpine's receiver converts each OTel span into one or more SteelSpine events:

OTel conceptSteelSpine event field
Span nameline
Span status code OK (1)kind: success
Span status code ERROR (2)kind: failure with error message appended to line
Span status code UNSET (0)kind: continuation
Instrumentation scope namelabel
Span events (sub-events)Each emitted as a child SteelSpine event
trace_id, span_idPreserved as otel_trace and otel_span metadata

Troubleshooting

Receiver starts but no events appear

"Connection refused" from the agent

HTTP 400 responses from the receiver

Events captured but missing context

What you can do with captured OTEL events

Once events are in SteelSpine, the full pipeline applies:

Related integrations