Deno

TracesMetricsApp LogsCustom LogsProfiling

Prerequisites#

  • Deno 1.41.2+. Check using:

    1deno --version
    Deno version check command for Middleware APM setup
  • If you choose Host-based mode, ensure the Middleware Host Agent is running and reachable from your app (see Host Agent install). In containers, set MW_AGENT_SERVICE to route traffic to the agent:

    • Docker: MW_AGENT_SERVICE=172.17.0.1 (default bridge gateway).
    • Kubernetes: MW_AGENT_SERVICE=mw-service.mw-agent-ns.svc.cluster.local.

Choose your deployment#

  • With Host Agent (same VM/pod as your app) → send OTLP to the local agent (http://localhost:9320).
  • Serverless (no agent) → send directly to Middleware ingest (https://<ACCOUNT-UID>.middleware.io:443).

1 Import the SDK and HTTP server#

Add these imports at the top of your entry file (e.g., index.ts).

1// index.ts
2import { serve } from "https://deno.land/[email protected]/http/server.ts";
3import { track, httpTracer, info, warn, error, debug } from "https://deno.land/x/[email protected]/mod.ts";

2 Initialize tracing#

Initialize once at startup. For host-based setups, send OTLP to the local Host Agent.

1// index.ts
2  track({
3    serviceName: "{APM-SERVICE-NAME}",
4    target: "http://localhost:9320",   // Host Agent OTLP HTTP endpoint
5    accessToken: "<MW_API_KEY>",
6  });

(The track(...) API mirrors the Middleware Deno doc; using a local collector is standard in host-based installs.)

3 Add a request handler#

Define how your server responds to incoming HTTP requests with the following function:

1// index.ts
2function handler(_req: Request): Response {
3  const data = { message: "Hello world!" };
4  return new Response(JSON.stringify(data), { headers: { "Content-Type": "application/json" } });
5}

4 Start the server with tracing#

Wrap the handler so incoming requests become spans; run with network permissions:

1// index.ts
2await serve(httpTracer(handler));
3deno run --allow-net index.ts

(Deno blocks network access by default; --allow-net grants it.)

5 (Optional) Send custom logs#

Wrap the handler so incoming requests become spans; run with network permissions:

1Emit structured logs that correlate with the active trace:
2info("Sample Info Log");
3warn("Sample Warning Log");
4error("Sample Error Log");
5debug("Sample Debug Log");

(Logging helpers are part of the same Deno SDK.)

Everything else stays the same. Only change the target to send data straight to the Middleware’s serverless ingest:

1// Only the target differs for serverless:
2track({
3  serviceName: "{APM-SERVICE-NAME}",
4  target: "https://<MW_UID>.middleware.io:443",
5  accessToken: "<MW_API_KEY>",
6});

On platforms like Deno Deploy, you don’t manage the HTTP process flags locally; you’ll still run with --allow-net for testing.

Environment variables#

Key/OptionPurposeExample
MW_AGENT_SERVICEIn containers, routes app → Host Agent172.17.0.1 (Docker) / mw-service.mw-agent-ns.svc.cluster.local (K8s).
serviceName (SDK option)Logical service name in APMorders-deno.
target (SDK option)OTLP endpointhttp://localhost:9320 (Host) or https://{ACCOUNT-UID}.middleware.io:443 (Serverless).
accessToken (SDK option)Middleware API key<MW_API_KEY>.
--allow-net (CLI)Network permission for local runsdeno run --allow-net index.ts.

Troubleshooting#

  • No traces/logs: Ensure track({...}) runs before requests and that you start via serve(httpTracer(handler)). In Host mode, confirm the Host Agent is running and the app can reach it (set MW_AGENT_SERVICE correctly in Docker/K8s).
  • Permission errors: Deno blocks the network by default. Run with --allow-net (you can scope it to specific hosts).
  • Imports drift: Pin remote module versions or use an import map in deno.json to centralize and lock dependencies.

Need assistance or want to learn more about Middleware? Get in touch with us via our Contact Us or join our Slack channel.