Skip to main content
GitHub

OpenTelemetry

Bridge Risicare with OpenTelemetry for unified observability.

Risicare supports full OpenTelemetry interoperability for unified observability.

Python only

The OpenTelemetry bridge is currently available in the Python SDK only.

OTel Bridge

Export Risicare spans to OpenTelemetry:

import risicare
 
risicare.init(
    api_key="rsk-...",
    otel_bridge=True,  # Enable OTel bridge
)

With the bridge enabled, all Risicare spans are also exported to the configured OTel collector.

OTLP Exporter

Export directly to OTLP-compatible backends:

risicare.init(
    api_key="rsk-...",
    otel_bridge=True,
    otlp_endpoint="http://localhost:4318/v1/traces",
    otlp_headers={"Authorization": "Bearer token"},
)

OTLP Ingestion

Risicare can receive spans from existing OTel instrumentation:

POST /v1/otlp/v1/traces
Content-Type: application/x-protobuf
Authorization: Bearer rsk-...

<OTLP trace data>

The double /v1/ is intentional — the first is the Risicare gateway route prefix, the second is the standard OTLP protocol path per the OpenTelemetry OTLP/HTTP specification.

This allows migrating existing OTel instrumentation to Risicare without code changes.

OTLPExporter Reference

For full control over OTLP export, create an OTLPExporter directly and pass it to init():

from risicare import OTLPExporter
 
exporter = OTLPExporter(
    endpoint="http://localhost:4318/v1/traces",
    headers={"Authorization": "Bearer token"},
    timeout_seconds=10.0,
    max_retries=3,
    compress=True,
    service_name="my-agent",
    service_version="1.0.0",
    environment="production",
)
 
risicare.init(
    api_key="rsk-...",
    exporters=[exporter],
)
ParameterTypeDefaultDescription
endpointstr"http://localhost:4318/v1/traces"OTLP/HTTP traces endpoint URL
headersdictNoneAdditional HTTP headers (e.g., auth tokens)
timeout_secondsfloat10.0HTTP request timeout
max_retriesint3Maximum retry attempts with exponential backoff
compressboolTruegzip-compress payloads
service_namestrNoneService name for OTLP resource attributes
service_versionstrNoneService version for OTLP resource attributes
environmentstrNoneDeployment environment for OTLP resource attributes

The exporter includes a circuit breaker (3 consecutive failures triggers a 30-second cooldown) and maps Risicare span attributes to gen_ai.* semantic conventions automatically.

Multiple Exporters

Export to multiple backends:

from risicare import OTLPExporter
from risicare.exporters.http import HttpExporter
from risicare.exporters.console import ConsoleExporter
 
risicare.init(
    api_key="rsk-...",
    exporters=[
        HttpExporter(),           # Risicare cloud
        OTLPExporter(             # Jaeger
            endpoint="http://jaeger:4318/v1/traces"
        ),
        ConsoleExporter(),        # Debug output
    ],
)

Semantic Conventions

Risicare follows OpenTelemetry semantic conventions for GenAI:

AttributeDescription
gen_ai.systemLLM provider (openai, anthropic, etc.)
gen_ai.request.modelRequested model name
gen_ai.response.modelActual model used
gen_ai.usage.prompt_tokensInput token count
gen_ai.usage.completion_tokensOutput token count
gen_ai.request.temperatureTemperature setting
gen_ai.request.max_tokensMax tokens setting

Context Propagation

W3C Trace Context is fully supported:

from risicare import inject_trace_context, extract_trace_context
 
# Inject into outgoing request
headers = {}
inject_trace_context(headers)
# headers now contains 'traceparent' and 'tracestate'
 
# Extract from incoming request
context = extract_trace_context(request.headers)

Existing OTel SDK

If you already use the OpenTelemetry Python SDK:

import risicare
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from risicare.integrations.otel import RisicareSpanProcessor
 
# Initialize Risicare first (required for the processor to work)
risicare.init(
    api_key="rsk-...",
)
 
# Add Risicare as a span processor (no constructor params needed)
provider = TracerProvider()
provider.add_span_processor(RisicareSpanProcessor())
trace.set_tracer_provider(provider)
 
# Existing OTel instrumentation now exports to Risicare

Next Steps