Trace a non-streaming Chat Completions request through the OpenAI client's fetch hook.
Datool supplies a fetch wrapper for non-streaming Chat Completions. It records each HTTP attempt, model input/output, status, and reported usage. Responses API calls and streaming requests pass through without this wrapper's model spans. Use manual tracing for those paths.
Use Node.js 22.18 or newer:
npm init -y
npm install @datool/sdk@0.3.1 openai @opentelemetry/api@1 @opentelemetry/sdk-trace-node@2Configure the three DATOOL_* variables from your first trace and an OPENAI_API_KEY in .env. The Datool key needs traces:write; the OpenAI key needs access to the selected model. The call uses your OpenAI account's quota.
Save openai.mjs:
import OpenAI from "openai"
import { trace } from "@opentelemetry/api"
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"
import { DatoolSpanProcessor } from "@datool/sdk/otel"
import { traceOpenAIChatFetch } from "@datool/sdk/openai"
const processor = new DatoolSpanProcessor()
const provider = new NodeTracerProvider({ spanProcessors: [processor] })
provider.register()
const openai = new OpenAI({
fetch: traceOpenAIChatFetch(trace.getTracer("docs-openai")),
})
try {
const result = await openai.chat.completions.create({
model: "gpt-4.1-mini",
messages: [{ role: "user", content: "Say hello in one sentence." }],
})
console.log(result.choices[0]?.message.content)
} finally {
try {
await processor.forceFlush()
} finally {
await provider.shutdown()
}
}node --env-file=.env openai.mjsOpen the resulting trace and inspect openai.chat.completions. Check the request model, returned model, input messages, assistant response, and usage. Missing provider usage or price coverage remains unavailable. OpenAI client retries can produce multiple attempt spans.
Do not apply this wrapper to an AI SDK client already emitting model spans. Configure Datool's processor only once per provider. Review capture and redaction before recording production messages.