# OpenTelemetry observability

Deno has built-in OpenTelemetry integration for runtime metrics, HTTP traces, `console` logs, and application-defined telemetry over OTLP.

## Shortest verification

```bash
OTEL_DENO=true \
OTEL_EXPORTER_OTLP_PROTOCOL=console \
deno run --allow-net main.ts
```

The console exporter confirms that signals exist. Production commonly targets an OTLP collector:

```bash
OTEL_DENO=true \
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318 \
OTEL_SERVICE_NAME=orders-api \
deno run --allow-net=0.0.0.0:8000,otel-collector:4318 main.ts
```

Runtime OTEL configuration and application calls to `Deno.env.get()` are different paths; the latter remains subject to `--allow-env`. In either case, put the telemetry endpoint, headers, and service name in an explicit configuration contract and never log header values.

## Custom spans

```ts
import { trace } from "npm:@opentelemetry/api";

const tracer = trace.getTracer("orders");
await tracer.startActiveSpan("create-order", async (span) => {
  try {
    span.setAttribute("order.channel", "web");
    // business operation
  } catch (error) {
    span.recordException(error as Error);
    throw error;
  } finally {
    span.end();
  }
});
```

## Production boundaries

- Never record tokens, cookies, Authorization, or full prompts as attributes.
- Propagate trace context across requests, databases, and tool calls.
- Bound sampling rate, export timeout, and queues.
- Observe exporter failures without letting telemetry block core requests.
- Use distinct service/environment attributes for local, CI, preview, and production.

Official source: [OpenTelemetry](https://docs.deno.com/runtime/fundamentals/open_telemetry/).
