DEV Community

Vigilmon
Vigilmon

Posted on

How to Monitor Your Deno App with Vigilmon

How to Monitor Your Deno App with Vigilmon

Deno is a secure, modern JavaScript and TypeScript runtime that's gaining traction for its built-in permissions model and first-class TypeScript support. But fast runtime ≠ always-up service. Production Deno apps need uptime monitoring just like any other backend.

In this tutorial you'll add a /health endpoint to a Deno HTTP server, wire it up to Vigilmon, and configure alerts so you know within minutes when something breaks.


What You'll Build

  • A minimal Deno HTTP server with a structured health-check endpoint
  • A Vigilmon monitor that polls the endpoint every 5 minutes from multiple regions
  • Email (and optionally webhook) alerts when the app goes down

Prerequisites

  • Deno v1.38+ installed
  • A free Vigilmon account (up to 5 monitors, no credit card required)

Step 1: Create a Deno HTTP Server with a Health Endpoint

Start with a basic Deno server that handles real routes and exposes a /health path:

// main.ts
const PORT = parseInt(Deno.env.get("PORT") ?? "8000");

async function handler(req: Request): Promise<Response> {
  const url = new URL(req.url);

  if (url.pathname === "/health") {
    const body = JSON.stringify({
      status: "ok",
      timestamp: new Date().toISOString(),
      version: "1.0.0",
    });
    return new Response(body, {
      status: 200,
      headers: { "Content-Type": "application/json" },
    });
  }

  if (url.pathname === "/") {
    return new Response("Hello from Deno!", { status: 200 });
  }

  return new Response("Not Found", { status: 404 });
}

console.log(`Server running on http://localhost:${PORT}`);
Deno.serve({ port: PORT }, handler);
Enter fullscreen mode Exit fullscreen mode

Run it:

deno run --allow-net --allow-env main.ts
Enter fullscreen mode Exit fullscreen mode

Test the health endpoint:

curl http://localhost:8000/health
# {"status":"ok","timestamp":"2024-01-15T10:30:00.000Z","version":"1.0.0"}
Enter fullscreen mode Exit fullscreen mode

The endpoint returns HTTP 200 with a JSON body — exactly what Vigilmon expects.


Step 2: Add a Deep Health Check

A shallow "always returns 200" endpoint misses real failures like a broken database connection. Add a deeper check that tests actual dependencies:

// health.ts
interface HealthStatus {
  status: "ok" | "degraded" | "down";
  checks: Record<string, boolean>;
  timestamp: string;
}

export async function buildHealthResponse(): Promise<[HealthStatus, number]> {
  const checks: Record<string, boolean> = {};

  // Example: check that a critical file/config is readable
  try {
    await Deno.stat("./config.json");
    checks.config = true;
  } catch {
    checks.config = false;
  }

  // Example: check an external dependency (replace with your DB/cache ping)
  try {
    const res = await fetch("https://httpbin.org/status/200", {
      signal: AbortSignal.timeout(3000),
    });
    checks.externalApi = res.ok;
  } catch {
    checks.externalApi = false;
  }

  const allOk = Object.values(checks).every(Boolean);
  const status: HealthStatus = {
    status: allOk ? "ok" : "degraded",
    checks,
    timestamp: new Date().toISOString(),
  };

  return [status, allOk ? 200 : 503];
}
Enter fullscreen mode Exit fullscreen mode

Update main.ts to use it:

import { buildHealthResponse } from "./health.ts";

// Inside handler:
if (url.pathname === "/health") {
  const [status, httpCode] = await buildHealthResponse();
  return new Response(JSON.stringify(status), {
    status: httpCode,
    headers: { "Content-Type": "application/json" },
  });
}
Enter fullscreen mode Exit fullscreen mode

Now the endpoint returns 503 when a dependency fails — Vigilmon treats non-2xx as a downtime event and fires an alert.


Step 3: Deploy Your Deno App

Before Vigilmon can monitor your app it needs to be publicly reachable. Common Deno hosting options:

Deno Deploy (official, free tier):

# Install deployctl
deno install --allow-read --allow-write --allow-env --allow-net --allow-run --no-check -r -f https://deno.land/x/deploy/deployctl.ts

# Deploy
deployctl deploy --project=my-deno-app main.ts
Enter fullscreen mode Exit fullscreen mode

Your app gets a URL like https://my-deno-app.deno.dev.

Docker / VPS (if you self-host):

FROM denoland/deno:1.40.0
WORKDIR /app
COPY . .
RUN deno cache main.ts
CMD ["run", "--allow-net", "--allow-env", "main.ts"]
Enter fullscreen mode Exit fullscreen mode

Note your public URL — you'll need it in the next step.


Step 4: Create a Vigilmon Monitor

  1. Log in at vigilmon.online and click + New Monitor.
  2. Set Monitor Type to HTTP / HTTPS.
  3. Paste your health endpoint URL, e.g. https://my-deno-app.deno.dev/health.
  4. Set Check Interval to 5 minutes (the free-tier minimum).
  5. Under Expected Status, leave it at 2xx (or enter 200 specifically).
  6. Click Save Monitor.

Vigilmon immediately begins polling from multiple geographic regions. If the majority of region checks fail it counts as a real outage — not a false alarm from a single-location blip.


Step 5: Configure Alert Channels

Email Alerts

Go to Settings → Alert Channels → Add Channel → Email, enter your address, and save. Assign the channel to your new monitor under Monitors → Edit → Alert Channels.

Webhook Alerts (Slack, PagerDuty, custom)

  1. Settings → Alert Channels → Add Channel → Webhook.
  2. Paste your Slack incoming-webhook URL (or any HTTPS endpoint).
  3. Vigilmon sends a JSON POST on every state change (up → down, down → up).

Example payload your endpoint receives:

{
  "monitor": "my-deno-app /health",
  "status": "down",
  "reason": "HTTP 503",
  "checked_at": "2024-01-15T10:31:00Z",
  "regions": ["us-east", "eu-west", "ap-south"]
}
Enter fullscreen mode Exit fullscreen mode

Step 6: Test the Alert Pipeline

Simulate a failure by returning 503 from your health endpoint:

// Temporarily force a failure to test alerting
if (url.pathname === "/health") {
  return new Response(JSON.stringify({ status: "down" }), { status: 503 });
}
Enter fullscreen mode Exit fullscreen mode

Redeploy, wait up to 5 minutes for the next check cycle, and you should receive an alert. Then revert and confirm you get the recovery notification.


Step 7: Add a Status Badge (Optional)

Vigilmon provides an embeddable badge you can add to your README or status page:

![Uptime](https://vigilmon.online/badge/<your-monitor-id>)
Enter fullscreen mode Exit fullscreen mode

Find your monitor ID in the Vigilmon dashboard URL (/monitors/123) and replace <your-monitor-id>.


Deno-Specific Tips

Permission scoping: Lock down your Deno permissions in production. If your app only needs network access, use --allow-net=0.0.0.0:8000 instead of --allow-net.

Deno Deploy edge functions: If you deploy to Deno Deploy's edge, add a separate monitor for each custom domain or region-specific URL you expose.

Graceful shutdown: Deno's Deno.addSignalListener("SIGTERM", ...) lets you drain connections cleanly before the process exits — Vigilmon will mark the app as down only after the check fails, not on the first missed ping.


Wrapping Up

In about 10 minutes you've gone from a bare Deno server to a production-monitored application:

  1. Health endpoint returning structured JSON with real dependency checks
  2. Vigilmon polling every 5 minutes from multiple regions
  3. Immediate alerts via email or Webhook when the app goes down

The free tier at vigilmon.online supports up to 5 monitors with no credit card required — plenty to cover a side project or early-stage product.


Have questions or found a better pattern for Deno health checks? Drop a comment below.

Top comments (0)