---
title: "Deno"
description: "Instrument Deno applications with the Middleware APM SDK to collect traces, metrics and logs, on Deno Deploy or a self-hosted Deno server."
section: "APM"
breadcrumb: "APM > Deno"
canonical: "https://docs.middleware.io/get-started/apm/deno"
---
# Deno

Use the Middleware APM SDK for Deno to send traces, metrics and application logs from Deno Deploy or a self-hosted Deno server to Middleware. The table shows which data types it collects.

| Traces | Metrics | App Logs | Custom Logs | Profiling |
| --- | --- | --- | --- | --- |
| ✅ | ✖ | ✖ | ✅ | ✖ |

## Prerequisites

- Deno 1.41.2+. Check using:

  ```bash
    deno --version
  ```

  ![Deno version check command for Middleware APM setup](/images/v2/apm/deno-version.png)
- 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`).

#### Host-based

#### 1 Import the SDK and HTTP server

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

```bash
  // index.ts
import { serve } from "https://deno.land/std@0.120.0/http/server.ts";
import { track, httpTracer, info, warn, error, debug } from "https://deno.land/x/middlewareio@v1.0.7/mod.ts";
```

#### 2 Initialize tracing

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

```bash
  // index.ts
  track({
    serviceName: "{APM-SERVICE-NAME}",
    target: "http://localhost:9320",   // Host Agent OTLP HTTP endpoint
    accessToken: "your-initial-token",
  });
```

(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:

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

#### 4 Start the server with tracing

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

```bash
  // index.ts
await serve(httpTracer(handler));
deno 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:

```bash
  Emit structured logs that correlate with the active trace:
info("Sample Info Log");
warn("Sample Warning Log");
error("Sample Error Log");
debug("Sample Debug Log");
```

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

#### Serverless

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

```bash
  // Only the target differs for serverless:
track({
  serviceName: "{APM-SERVICE-NAME}",
  target: "your-initial-uid",
  accessToken: "your-initial-token",
});
```

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/Option | Purpose | Example |
| --- | --- | --- |
| `MW_AGENT_SERVICE` | In containers, routes app → Host Agent | `172.17.0.1` (Docker) / `mw-service.mw-agent-ns.svc.cluster.local` (K8s). |
| `serviceName (SDK option)` | Logical service name in APM | `orders-deno.` |
| `target` (SDK option) | OTLP endpoint | `http://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 runs | `deno 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 page or join our Slack channel.
