Skip to main content

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:
ActionDetails
Agent discoveryNew service.name values appear in Discovery as UNREVIEWED
Execution recordingEach agent span stored as a connector execution
Cost trackingToken usage attributes → cost events (for approved agents)
Quality inferenceCheck inference runs server-side on each execution

Supported semantic conventions

AttributeDescription
service.nameAgent name (required)
gen_ai.usage.input_tokensPrompt token count (GenAI convention)
gen_ai.usage.output_tokensCompletion token count (GenAI convention)
gen_ai.response.modelModel name
gen_ai.request.modelRequested model name
llm.usage.prompt_tokensPrompt tokens (LangChain format)
llm.usage.completion_tokensCompletion tokens (LangChain format)
llm.model_nameModel 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.

Why OTel instead of a platform connector?

OTelPlatform connector
Code changes3 env varsNone
Framework coverageUniversalPer-platform only
Data richnessFull traces + spansAPI metadata only
LatencyReal-timePolling (minutes)
Works on no-code tools (n8n, Flowise)NoYes
Use OTel for custom-coded agents. Use platform connectors for no-code/low-code tools where you can’t set env vars.