Skip to content

Latest commit

 

History

History
163 lines (124 loc) · 5.46 KB

File metadata and controls

163 lines (124 loc) · 5.46 KB
description Fresh has built-in OpenTelemetry instrumentation for tracing requests through middleware, handlers, and rendering.

Fresh automatically instruments key operations with OpenTelemetry spans, giving you visibility into how requests flow through your application. No code changes are needed - just configure an exporter.

What's instrumented

Fresh creates spans for:

  • Middleware execution - each middleware in the chain
  • Route handler execution - handler function calls
  • Rendering - server-side page rendering, including async components
  • Static file serving - file lookups, caching, and responses
  • Lazy route loading - dynamic imports of route modules on first access

All spans are created under the fresh tracer (named with the current Fresh version). The root span for each request includes http.route with the matched route pattern (e.g. GET /blog/:slug), making it easy to group traces by route.

Enabling tracing

Fresh uses the @opentelemetry/api package (the vendor-neutral API). Spans are created automatically - you just need to provide an OpenTelemetry SDK and exporter to collect them.

If no exporter is configured, the spans are silently discarded with no performance overhead.

With Deno's built-in OpenTelemetry

Deno has built-in OpenTelemetry support. Enable it with the OTEL_DENO environment variable:

OTEL_DENO=true deno task start

By default, Deno exports telemetry using OTLP over HTTP/protobuf to http://localhost:4318. Set a service name so your application is easy to find in your observability backend, and configure the endpoint when the collector runs elsewhere:

OTEL_DENO=true \
OTEL_SERVICE_NAME=my-fresh-app \
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 \
deno task start

See Deno's OpenTelemetry configuration for other supported exporter protocols and options.

With Deno Deploy

Deno Deploy collects Fresh traces automatically when using the Fresh preset - no configuration needed. Traces appear in the Deno Deploy dashboard.

With a custom exporter

You can use any OpenTelemetry-compatible backend (Jaeger, Zipkin, Honeycomb, Grafana Tempo, Datadog, etc.). Install the SDK and configure an exporter in your entry point:

import { NodeSDK } from "@opentelemetry/sdk-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";

const sdk = new NodeSDK({
  traceExporter: new OTLPTraceExporter({
    url: "https://your-collector.example.com/v1/traces",
  }),
});
sdk.start();

Span attributes

Fresh sets the following attributes on spans:

Attribute Span type Description
http.route Root The matched route pattern (e.g. /blog/:slug)
fresh.span_type Various Internal span classification (render, etc.)
fresh.cache Static file Cache status (immutable, not_modified, no_cache, invalid_bust_key)
fresh.cache_key Static file The cache bust key for the asset

Errors in handlers or rendering are recorded on the span with span.recordException() and the span status is set to ERROR.

Local development

Console exporter

The quickest way to see traces is to print them to the console. Deno (2.7+) supports this out of the box - no extra dependencies or services needed:

OTEL_DENO=true \
OTEL_EXPORTER_OTLP_PROTOCOL=console \
OTEL_SERVICE_NAME=my-fresh-app \
deno task start

The console protocol does not require an endpoint. Each request prints its spans directly to stderr, showing the full breakdown of middleware, handler, and rendering timings.

Jaeger

For a visual trace explorer, run Jaeger locally with Docker:

docker run -d --name jaeger \
  -p 16686:16686 \
  -p 4317:4317 \
  jaegertracing/all-in-one:latest

Deno 2.8+ can send directly to Jaeger's OTLP gRPC collector:

OTEL_DENO=true \
OTEL_EXPORTER_OTLP_PROTOCOL=grpc \
OTEL_SERVICE_NAME=my-fresh-app \
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 \
deno task start

Open http://localhost:16686 to browse traces. You'll see each request broken down into its middleware, handler, and rendering spans.

Client-side trace correlation

When an OpenTelemetry exporter is active, Fresh automatically injects a W3C Trace Context <meta> tag into the <head> of every rendered page:

<head>
  <meta
    name="traceparent"
    content="00-ab42124a3c573678d4d8b21ba52df3bf-d21f7bc17caa5aba-01"
  >
  <!-- ... -->
</head>

This allows client-side OpenTelemetry instrumentation (such as @opentelemetry/instrumentation-document-load) to link browser performance traces back to the server-side span that rendered the page, giving you end-to-end visibility from server rendering through page load.