Applies to:
- Plan:
- Deployment:
OTEL_EXPORTER_OTLP_ENDPOINT=https://api.braintrust.dev/otel
OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer , x-bt-parent=project_name:"
// Java example using OpenTelemetry
Span sessionSpan = tracer.spanBuilder("voice_interaction")
.setAttribute("braintrust.input", userSpeechText)
.setAttribute("braintrust.metadata", JSON.toJson(Map.of(
"user_id", "user-123",
"session_id", "session-456",
"audio_duration_ms", 2500
)))
.setAttribute("braintrust.tags", JSON.toJson(List.of("voice", "realtime-api")))
.startSpan();
// Nested span for RAG retrieval
Span retrievalSpan = tracer.spanBuilder("rag_retrieval")
.setParent(Context.current().with(sessionSpan))
.setAttribute("braintrust.metadata", JSON.toJson(Map.of(
"documents_considered", List.of(
Map.of("id", "kb_123", "title", "Product FAQ", "relevance", 0.92),
Map.of("id", "kb_456", "title", "User Guide", "relevance", 0.78)
),
"retrieval_method", "semantic_search"
)))
.startSpan();
// Store conversation data for scoring
sessionSpan.setAttribute("braintrust.output", llmResponse);
sessionSpan.setAttribute("braintrust.metadata", JSON.toJson(Map.of(
"conversation_history", conversationMessages,
"rag_documents", retrievedDocuments,
"total_tokens", tokenCount,
"session_duration_ms", sessionDuration
)));
// End nested spans first
retrievalSpan.end();
// End session span when WebSocket closes
sessionSpan.setAttribute("braintrust.metrics", JSON.toJson(Map.of(
"total_messages", messageCount,
"total_duration_ms", sessionDuration
)));
sessionSpan.end();
// Flush telemetry data
OpenTelemetry.getGlobalOpenTelemetry().shutdown();
Was this page helpful?