OpenAI
The OpenTelemetry GenAI instrumentation patches the OpenAI SDK, so every model call is traced with no code change at the call site.
You will need:
OODLE_INSTANCE: your Oodle instance ID (ap1, us1)OODLE_API_KEY: an Oodle API key (ap1, us1)OTLP_ENDPOINT: your OTLP collector domain, shown on the tile
Open the OpenAI tile on the ap1, us1 page to
get these filled in for you, or let an agent do the setup with
/oodle-onboarding set up the llm_observability_openai integration.
Python
Install
Install the OpenTelemetry GenAI instrumentation:
pip install opentelemetry-instrumentation-openai-v2 \
opentelemetry-exporter-otlp-proto-http \
opentelemetry-sdk \
httpx \
openai
Instrument
Initialize OpenTelemetry and activate the GenAI instrumentor. After this, all LLM SDK calls are automatically traced:
from opentelemetry import _logs as otel_logs
from opentelemetry import trace as otel_trace
from opentelemetry.exporter.otlp.proto.http._log_exporter import OTLPLogExporter
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor
from opentelemetry.sdk._logs import LoggerProvider
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
def setup_opentelemetry():
resource = Resource.create({"service.name": "my-llm-app"})
tracer_provider = TracerProvider(resource=resource)
tracer_provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
otel_trace.set_tracer_provider(tracer_provider)
logger_provider = LoggerProvider(resource=resource)
logger_provider.add_log_record_processor(
BatchLogRecordProcessor(OTLPLogExporter())
)
otel_logs.set_logger_provider(logger_provider)
setup_opentelemetry()
OpenAIInstrumentor().instrument()
Environment
Point the application at Oodle:
# OTLP endpoint (points straight at Oodle)
export OTEL_EXPORTER_OTLP_ENDPOINT=https://<OTLP_ENDPOINT>
export OTEL_EXPORTER_OTLP_HEADERS="X-API-KEY=<OODLE_API_KEY>,X-OODLE-INSTANCE=<OODLE_INSTANCE>"
# Enable GenAI semantic conventions
export OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental
# Capture prompt/response content
export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=span_and_event
TypeScript / JavaScript
Install
Install the OpenTelemetry GenAI instrumentation:
npm install @opentelemetry/instrumentation-openai \
@opentelemetry/instrumentation \
@opentelemetry/exporter-trace-otlp-proto \
@opentelemetry/exporter-logs-otlp-proto \
@opentelemetry/resources \
@opentelemetry/sdk-trace-base \
@opentelemetry/sdk-trace-node \
@opentelemetry/sdk-logs \
@opentelemetry/semantic-conventions \
"openai@^6"
Instrument
Initialize OpenTelemetry and activate the GenAI instrumentor. After this, all LLM SDK calls are automatically traced:
// instrumentation.js
const { OpenAIInstrumentation } = require('@opentelemetry/instrumentation-openai');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-proto');
const { resourceFromAttributes } = require('@opentelemetry/resources');
const { BatchSpanProcessor } = require('@opentelemetry/sdk-trace-base');
const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { ATTR_SERVICE_NAME } = require('@opentelemetry/semantic-conventions');
const { OTLPLogExporter } = require('@opentelemetry/exporter-logs-otlp-proto');
const { BatchLogRecordProcessor, LoggerProvider } = require('@opentelemetry/sdk-logs');
const provider = new NodeTracerProvider({
resource: resourceFromAttributes({ [ATTR_SERVICE_NAME]: 'my-llm-app' }),
spanProcessors: [new BatchSpanProcessor(new OTLPTraceExporter())],
});
provider.register();
// The instrumentation writes prompts and responses as log
// records. Registering it without a logger provider yields
// spans that carry no content.
const loggerProvider = new LoggerProvider({
resource: resourceFromAttributes({ [ATTR_SERVICE_NAME]: 'my-llm-app' }),
processors: [
new BatchLogRecordProcessor({ exporter: new OTLPLogExporter() }),
],
});
registerInstrumentations({
instrumentations: [new OpenAIInstrumentation()],
loggerProvider,
});
process.on('beforeExit', async () => {
await provider.shutdown();
await loggerProvider.shutdown();
});
Environment
Point the application at Oodle:
# OTLP endpoint (points straight at Oodle)
export OTEL_EXPORTER_OTLP_ENDPOINT=https://<OTLP_ENDPOINT>
export OTEL_EXPORTER_OTLP_HEADERS="X-API-KEY=<OODLE_API_KEY>,X-OODLE-INSTANCE=<OODLE_INSTANCE>"
# Capture prompt/response content
export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true
# Load the instrumentation before your app, so the OpenAI
# SDK is patched as it loads.
node --require ./instrumentation.js app.js
Verify
Run your application, then open ap1, us1. Spans
carry gen_ai.* attributes: the model, token counts, and the prompt and
response content. Click a trace for the Transcript, the waterfall, and
the cost breakdown.
If nothing arrives, check that the exporter can reach
https://<OTLP_ENDPOINT> and that the instance and key are set: the
OTLP gateway answers 401 without them.
Support
If you need assistance or have any questions, please reach out to us through:
- Email at [email protected]