OpenTelemetry
@flue/opentelemetry projects Flue’s live runtime observations into standard OpenTelemetry GenAI spans and metrics. It does not configure an SDK, exporter, sampling, credentials, or deployment-specific flushing.
The package implements the Development GenAI conventions pinned at commit 4c8addb53718b544134be47e256237026fe88875. Its Flue-to-GenAI projection revision is 5 and its Flue extension revision is 3; the GenAI semantic-convention revision and schema remain unchanged. Updating any revision requires an explicit compatibility review.
Configure
Install the adapter and OpenTelemetry API alongside an SDK and exporter compatible with your deployment target:
pnpm add @flue/opentelemetry @opentelemetry/api
Configure the SDK first, then register one instrumentation instance:
import { createOpenTelemetryInstrumentation } from '@flue/opentelemetry';
import { instrument } from '@flue/runtime';
const instrumentation = createOpenTelemetryInstrumentation();
const disposeInstrumentation = instrument(instrumentation);
Pass configured tracer, meter, or structural Logger instances when the application owns them. Generated Node applications automatically dispose registrations created while evaluating app.ts after admissions and active work drain. Call await disposeInstrumentation() yourself only when registering outside that lifecycle, then flush or shut down the application-owned SDK/exporter separately.
Trace model
- A prompt or skill operation becomes
invoke_agent <agent>. - A delegated task becomes one task-owned
invoke_agent <agent>. - Provider inference becomes a
chat <requested-model>client span. - A GenAI tool execution becomes
execute_tool <name>. - A caller shell execution becomes
flue.operation shell. - A context compaction becomes
flue.compactionwith child chat spans.
Provider chat spans cover provider inference only. The projection reads canonical model telemetry directly: semantic request.providerName becomes gen_ai.provider.name, while request.providerId remains the Flue registration identity. Local tools are sibling spans under the agent invocation and correlate with model output through gen_ai.tool.call.id.
gen_ai.conversation.id identifies one persisted Flue session. It is not a submission, dispatch, operation, trace, session name, or provider-affinity key. Flue correlation fields remain under documented flue.* attributes when no exact standard field exists.
Protect content
Content is disabled by default. This excludes implemented model messages, reasoning, system instructions, tool definitions, descriptions, arguments/results, exception messages and stack traces, and external-content paths.
Use one instrumentation-wide policy to enable and redact content:
const instrumentation = createOpenTelemetryInstrumentation({
content: {
enabled: process.env.OTEL_GENAI_CAPTURE_CONTENT === 'true',
transform(content) {
return redactSecrets(content);
},
},
});
The enabled value is the global privacy ceiling. A detached converted value passes through transform once; returning undefined suppresses both destinations. Transforms are trusted application code; Flue does not validate their returned GenAI shape. Structural limits run afterward: maxMessageParts retains the first complete parts per input/output message and first top-level system instructions, and maxToolDefinitions retains the first definitions. Limit values must be finite nonnegative safe integers.
externalContent is a side-effect-only sink for system instructions and input/output messages. It receives a detached, structurally limited clone with a stable contentType scope regardless of span sampling or inline. Returns and mutations cannot alter inline content, failures only diagnose, and tool content is never delivered. Set inline: false to skip serialization while retaining this external delivery.
maxAttributeBytes measures the exact final UTF-8 inline string and does not limit external delivery. Object-shaped tool arguments/results use standard gen_ai.tool.call.* attributes; strings, arrays, primitives, and null use flue.tool.call.arguments or flue.tool.call.result under the same privacy and size policy. Tool descriptions and plain-text fallbacks remain raw strings. Bounded flue.telemetry.content.* attributes mark structural truncation and inline byte omission. The adapter does not invent flattened child keys beneath gen_ai.*.
Metrics and Logs
The instrumentation emits client-operation, token-usage, agent-invocation, and tool-duration histograms. Metric dimensions exclude execution IDs; review your application-controlled agent, tool, provider, and model names for appropriate cardinality. Input token totals include cache-read and cache-creation input tokens.
Logs require explicit Logger injection. Failed inference operations emit the standard gen_ai.client.operation.exception event at WARN/13. Error type is always recorded; transformed exception messages and throw-site stack traces (exception.stacktrace) are included only when content capture is enabled. Logger absence does not affect traces or metrics.
Propagation and recovery
Flue validates and persists traceparent and optional tracestate at direct-agent admission. Baggage is not persisted. Durable direct-agent processing activates its extracted admission context, and execution interceptors activate owning spans around agent, model-stream, tool, and task work. dispatch(...) does not currently propagate trace context.
Recovery does not replay provider or tool execution. Stored stream chunks create no chat spans or usage observations, and synthetic interrupted-tool repairs create no execute_tool spans.
Streaming limitation
Pi does not expose authoritative raw provider stream-item timing. Flue therefore omits time-to-first-chunk and time-per-output-chunk metrics instead of deriving inaccurate values from semantic text/reasoning deltas or recovered chunks.
Unsupported operations
Flue does not emit invented spans for agent creation, planning, embeddings, retrieval, memory operations, remote agent clients, or evaluations. These operations remain absent until Flue exposes a genuine corresponding boundary.
Verify
Use an in-memory OpenTelemetry exporter in tests to verify hierarchy, names, kinds, status, attributes, metrics, and default content omission. Hosted backend rendering is backend-specific; standards-correct OTel output is the portable contract.