How it works
OpenTelemetry (OTel) ingestion is built directly into the Muster backend. There is no sidecar connector to deploy — your agents export traces straight to your Muster instance over HTTPS.
This gives full coverage across:
- Any language (Python, Go, Java, Node.js, Rust)
- Any framework with OTel support (LangChain, CrewAI, LlamaIndex, custom agents)
- Agents that don’t have a dedicated Muster connector
What your developers do
Set three environment variables on your agent. That’s it.
OTEL_EXPORTER_OTLP_ENDPOINT=https://backend.YOUR-INSTANCE.getmuster.io/api/v1/otel
OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer <muster-jwt-token>
OTEL_EXPORTER_OTLP_PROTOCOL=http/json
Get the JWT by calling POST /auth/login with a service account user, or copy it from your Muster dashboard → Settings → API Access.
No code changes are required if your agent already emits OTel spans.
Adding OTel to a Python agent
If your agent doesn’t yet emit OTel spans, add instrumentation once at startup:
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
import os
# Configure once at startup
provider = TracerProvider()
provider.add_span_processor(
BatchSpanProcessor(OTLPSpanExporter(
endpoint=os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] + "/v1/traces",
headers={"Authorization": f"Bearer {os.environ['MUSTER_JWT']}"},
))
)
trace.set_tracer_provider(provider)
tracer = trace.get_tracer("my-agent", service_name="invoice-processor")
# Instrument your agent runs
def run_agent(input: str) -> str:
with tracer.start_as_current_span("agent.run") as span:
span.set_attribute("service.name", "invoice-processor")
result = llm.invoke(input)
span.set_attribute("gen_ai.usage.input_tokens", result.usage.prompt_tokens)
span.set_attribute("gen_ai.usage.output_tokens", result.usage.completion_tokens)
span.set_attribute("gen_ai.response.model", "gpt-4o")
return result.content
The service.name attribute becomes the agent name in Muster. New service names are auto-added to your Discovery queue for review.
LangChain — zero-code instrumentation
If you use LangChain, one line enables automatic tracing of all chains and agents:
from opentelemetry.instrumentation.langchain import LangchainInstrumentor
LangchainInstrumentor().instrument()
# All chains, agents, and LLM calls now emit OTel spans automatically
Then set the three env vars above and Muster receives full trace data immediately.
Check connection status
GET /api/v1/otel/status
Authorization: Bearer <token>
Returns current connector status, executions received in the last 24 hours, and the exact env vars to use for your instance.
What Muster does automatically
Once traces arrive:
| Action | Details |
|---|
| Agent discovery | New service.name values appear in Discovery as UNREVIEWED |
| Execution recording | Each agent span stored as a connector execution |
| Cost tracking | Token usage attributes → cost events (for approved agents) |
| Quality inference | Check inference runs server-side on each execution |
Supported semantic conventions
| Attribute | Description |
|---|
service.name | Agent name (required) |
gen_ai.usage.input_tokens | Prompt token count (GenAI convention) |
gen_ai.usage.output_tokens | Completion token count (GenAI convention) |
gen_ai.response.model | Model name |
gen_ai.request.model | Requested model name |
llm.usage.prompt_tokens | Prompt tokens (LangChain format) |
llm.usage.completion_tokens | Completion tokens (LangChain format) |
llm.model_name | Model name (LangChain format) |
Supported agent span names
Muster identifies root agent executions from these span names (partial match):
agent.run, agent.execute, agent.invoke, langchain.chain, langchain.agent,
crewai.task, crewai.agent, openai.chat, anthropic.messages,
bedrock.invoke, llm.completion, chain.run, tool.run
To add custom span names, contact Elitery.
| OTel | Platform connector |
|---|
| Code changes | 3 env vars | None |
| Framework coverage | Universal | Per-platform only |
| Data richness | Full traces + spans | API metadata only |
| Latency | Real-time | Polling (minutes) |
| Works on no-code tools (n8n, Flowise) | No | Yes |
Use OTel for custom-coded agents. Use platform connectors for no-code/low-code tools where you can’t set env vars.