Skip to content

Deno ​

OpenTelemetry is built into Deno, so there's nothing to install. Turning it on yields traces for Deno.serve and fetch, HTTP server metrics, and every console.log as a log.

Prerequisites

An OpenTelemetry Stream and an ingest key for that Stream. See OpenTelemetry → Prerequisites. Deno 2.4 or newer is required.

1. Configure ​

bash
OTEL_DENO=true
OTEL_SERVICE_NAME=checkout-api
OTEL_EXPORTER_OTLP_ENDPOINT=https://ws.latency.app/v1/ingest
OTEL_EXPORTER_OTLP_HEADERS=authorization=Bearer%20lit_XXXXXXXXXXX
OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=delta

OTEL_DENO=true is the switch. Deno already sends over HTTP, so there's no protocol to set.

Deno always sends all three signals, and one OpenTelemetry Stream takes them all.

2. Run ​

Start the app as usual:

bash
deno run -A main.ts

3. Check it's working ​

Make a few requests to the app, then open Telemetry in the Console, pick the Stream and choose Traces. Traces show up within seconds. Metrics follow within a minute.

Custom spans ​

Deno sets up @opentelemetry/api automatically, so a plain import works:

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

const tracer = trace.getTracer("checkout");

await tracer.startActiveSpan("charge-card", async (span) => {
  try {
    span.setAttribute("order.id", order.id);
    await chargeCard(order);
  } finally {
    span.end();
  }
});

Custom metrics ​

ts
import { metrics } from "npm:@opentelemetry/api@1";

const meter = metrics.getMeter("checkout");
const orders = meter.createCounter("orders.placed");
const duration = meter.createHistogram("checkout.duration", { unit: "ms" });

orders.add(1, { plan: "pro" });
duration.record(182, { route: "/pay" });

Logs ​

Every console.log, console.warn and console.error goes to the Stream's logs, linked to the surrounding trace, and still prints to the terminal. To send logs to Telemetry only, set OTEL_DENO_CONSOLE=replace; to keep console output out of Telemetry, set OTEL_DENO_CONSOLE=ignore.

© 2026 Latency Labs LLC