Dual Export
Send traces from existing observability providers to Judgment.
Dual export lets you keep an existing OpenTelemetry-compatible tracing provider while sending the same spans to Judgment. Use this when your current tool exposes an OpenTelemetry span processor, tracer provider, or OTLP exporter, such as Logfire, Langfuse, LangSmith, or Braintrust.
If your current provider does not expose OpenTelemetry or OTLP export, use Judgment tracing directly instead.
Setup
Create a standard OpenTelemetry OTLP exporter for Judgment, then attach it to your existing provider's tracing pipeline.
uv add opentelemetry-sdk opentelemetry-exporter-otlp-proto-httppip install opentelemetry-sdk opentelemetry-exporter-otlp-proto-httpSet your Judgment credentials:
export JUDGMENT_API_KEY="<JUDGMENT_API_KEY>"
export JUDGMENT_ORG_ID="<JUDGMENT_ORG_ID>"
export JUDGMENT_PROJECT_ID="<JUDGMENT_PROJECT_ID>"Create this local helper in your app:
import os
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace.export import BatchSpanProcessor
def create_judgment_processor() -> BatchSpanProcessor:
return BatchSpanProcessor(
OTLPSpanExporter(
endpoint="https://api.judgmentlabs.ai/otel/v1/traces",
headers={
"Authorization": f"Bearer {os.environ['JUDGMENT_API_KEY']}",
"X-Organization-Id": os.environ["JUDGMENT_ORG_ID"],
"X-Project-Id": os.environ["JUDGMENT_PROJECT_ID"],
},
)
)Provider Examples
Pydantic Logfire
Logfire accepts extra OpenTelemetry span processors through
additional_span_processors.
import logfire
from openai import OpenAI
from judgment_otlp import create_judgment_processor
logfire.configure(
token="<LOGFIRE_WRITE_TOKEN>",
service_name="my-agent",
environment="production",
send_to_logfire=True,
additional_span_processors=[create_judgment_processor()],
)
logfire.instrument_openai()
client = OpenAI()
response = client.chat.completions.create(
model="gpt-5.2",
messages=[{"role": "user", "content": "Hello"}],
)
print(response.choices[0].message.content)Your OpenAI spans now go to both Logfire and Judgment.
Langfuse
Langfuse accepts a custom OpenTelemetry tracer provider. Add Judgment to that provider, then pass the same provider to Langfuse.
import os
from langfuse import Langfuse
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from judgment_otlp import create_judgment_processor
provider = TracerProvider()
provider.add_span_processor(create_judgment_processor())
trace.set_tracer_provider(provider)
langfuse = Langfuse(
public_key=os.environ["LANGFUSE_PUBLIC_KEY"],
secret_key=os.environ["LANGFUSE_SECRET_KEY"],
tracer_provider=provider,
)Keep your existing Langfuse instrumentation. Langfuse adds its own processor to the shared provider, so spans created on this provider are seen by both Langfuse and Judgment.
LangSmith
LangSmith supports sending OpenTelemetry traces to an alternate provider. Point
that alternate OTLP exporter at Judgment and leave LANGSMITH_OTEL_ONLY unset
so traces still go to LangSmith.
import os
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from judgment_otlp import create_judgment_processor
os.environ["LANGSMITH_OTEL_ENABLED"] = "true"
os.environ["LANGSMITH_TRACING"] = "true"
provider = TracerProvider()
provider.add_span_processor(create_judgment_processor())
trace.set_tracer_provider(provider)
prompt = ChatPromptTemplate.from_template("Tell me a joke about {topic}")
model = ChatOpenAI()
chain = prompt | model
result = chain.invoke({"topic": "programming"})
print(result.content)Set LANGSMITH_OTEL_ONLY="true" only if you want to send traces to Judgment
without also sending them to LangSmith.
Braintrust
Braintrust exposes an OpenTelemetry span processor. Add Judgment beside it on the same provider.
import os
from braintrust.otel import BraintrustSpanProcessor
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from judgment_otlp import create_judgment_processor
provider = TracerProvider()
provider.add_span_processor(
BraintrustSpanProcessor(parent="project_name:my-braintrust-project")
)
provider.add_span_processor(create_judgment_processor())
trace.set_tracer_provider(provider)Your existing OpenTelemetry or Braintrust-compatible instrumentation now exports to both Braintrust and Judgment.
Next Steps
- Tracing - Learn how Judgment displays traces, spans, sessions, and LLM metadata.
- OpenTelemetry integrations - Add automatic LLM instrumentation before dual exporting.