Skip to main content
Opik Documentation

Search documentation

Type to search this documentation.

On this pageOverview

OpenTelemetry

Opik provides native support for OpenTelemetry (OTel), allowing you to instrument your ML/AI applications with distributed tracing. This guide will show you how to directly integrate OpenTelemetry SDKs with Opik.

To start sending traces to Opik, configure your OpenTelemetry exporter with one of these endpoints:

wordWrap
export OTEL_EXPORTER_OTLP_ENDPOINT="https://www.comet.com/opik/api/v1/private/otel"
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=<your-api-key>,projectName=<your-project-name>,Comet-Workspace=<your-workspace-name>"
wordWrap
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:5173/api/v1/private/otel"
wordWrap
export OTEL_EXPORTER_OTLP_ENDPOINT="https://<comet deployment url>/opik/api/v1/private/otel"
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=<your-api-key>,projectName=<your-project-name>,Comet-Workspace=<your-workspace-name>"

If your OpenTelemetry setup requires signal-specific configuration, you can use the traces endpoint. This is particularly useful when different signals (traces, metrics, logs) need to be sent to different endpoints:

wordWrap
export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://<YOUR-OPIK-INSTANCE>/api/v1/private/otel/v1/traces"

You can use any OpenTelemetry SDK to send traces directly to Opik. OpenTelemetry provides SDKs for many languages (C++, .NET, Erlang/Elixir, Go, Java, JavaScript, PHP, Python, Ruby, Rust, Swift). This extends Opik's language support beyond the official SDKs (Python and TypeScript). For more instructions, visit the OpenTelemetry documentation.

Here's a Python example showing how to set up OpenTelemetry with Opik:

wordWrap
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.http.trace_exporter import (
    OTLPSpanExporter
)
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

# For Comet-hosted installations
OPIK_ENDPOINT = "https://<COMET-SERVER>/api/v1/private/otel/v1/traces"
API_KEY = "<your-api-key>"
PROJECT_NAME = "<your-project-name>"
WORKSPACE_NAME = "<your-workspace-name>"

# Initialize the trace provider
provider = TracerProvider()
processor = BatchSpanProcessor(
    OTLPSpanExporter(
        endpoint=OPIK_ENDPOINT,
        headers={
            "Authorization": API_KEY,
            "projectName": PROJECT_NAME,
            "Comet-Workspace": WORKSPACE_NAME
        }
    )
)
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)

Opik reads a small set of span attributes and maps them to Opik fields. Set them with the standard OpenTelemetry API on any span.

Attribute Effect
opik.tags Adds tags to the span. On the root span, Opik also adds the tags to the trace, so you can filter your traces by tag.
opik.metadata.<key> Adds <key> to the metadata of the span. The metadata of the root span also becomes the metadata of the trace.
thread_id Groups traces into one conversational thread. See Multi-turn conversations.
opik.trace_id, opik.parent_span_id, opik.span_id Attaches the span to an Opik trace and parent span that already exist. See Distributed traces.

Opik accepts three formats for the opik.tags attribute:

  • A list of strings: ["production", "chatbot"]
  • A JSON array in a string: '["production", "chatbot"]'
  • A comma-separated string: "production,chatbot"
wordWrap
with tracer.start_as_current_span("chatbot_conversation") as conversation_span:
    # The root span carries the tags, so the trace carries them too
    conversation_span.set_attribute("opik.tags", ["production", "chatbot"])
    conversation_span.set_attribute("opik.metadata.environment", "staging")

    with tracer.start_as_current_span("llm_completion") as llm_span:
        # A child span carries the tags on the span only
        llm_span.set_attribute("opik.tags", ["llm-call"])
Suggest an edit

Propose a replacement for this page. The site team reviews it before applying any changes.

Export
Documentation menu