|Docs

Tracing for Deno

Deno has OpenTelemetry built into the runtime. One environment variable turns on spans for Deno.serve requests and fetch calls, with export over OTLP to Railway's collector. No packages are needed.

Before you start, enable tracing for the service. Railway adds the OTEL_* variables on the next deploy, and Deno reads them.

Enable OpenTelemetry in Deno

Set this variable on the service:

OTEL_DENO=true

Deno reads OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_PROTOCOL, OTEL_EXPORTER_OTLP_HEADERS, and OTEL_SERVICE_NAME from the variables Railway provides, and exports over OTLP/HTTP.

By default, Deno also exports every console.* call as a log record. Railway's receiver accepts traces only, and Railway already captures your service's standard output as logs, so turn the export off:

OTEL_DENO_CONSOLE=ignore

What Deno instruments

With OpenTelemetry enabled, Deno creates spans without any code changes for:

  • Incoming requests handled by Deno.serve
  • Outgoing fetch requests, with the trace context injected into the request headers
  • node:http2 traffic
  • Deno.cron invocations

Deno propagates W3C Trace Context, so a request the edge traced continues in the same trace inside your service, and a fetch to another Railway service carries the trace onward.

Add a custom span

Use the @opentelemetry/api package from npm to create spans. Deno's runtime provides the tracer behind the API, so the package is the only dependency:

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

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

async function calculateTotal(cart: Cart) {
  return tracer.startActiveSpan("calculate-total", async (span) => {
    try {
      span.setAttribute("cart.items", cart.items.length);
      return await priceItems(cart);
    } catch (err) {
      span.setStatus({ code: SpanStatusCode.ERROR });
      throw err;
    } finally {
      span.end();
    }
  });
}

Verify

  1. Deploy the service and send it a few requests.
  2. Open the Traces page. In the Tracing setup panel, the App indicator for the service turns green when its first span arrives.
  3. Open a trace. The Deno.serve span and any fetch spans appear under the edge and proxy spans.

If spans from the app don't arrive, see Troubleshooting. For the full list of variables Deno reads, see the Deno OpenTelemetry documentation.