tutorial

How to Monitor Asdf-VM Managed Services with Vigilmon

Asdf-VM is the extensible version manager that lets teams pin exact runtime versions — Node.js, Python, Ruby, Go, and dozens more — per project via a single ...

Asdf-VM is the extensible version manager that lets teams pin exact runtime versions — Node.js, Python, Ruby, Go, and dozens more — per project via a single .tool-versions file. It eliminates "works on my machine" version drift. But when the services those runtimes power go down, Asdf-VM itself won't tell you.

In this tutorial you'll add external uptime monitoring to services built and run with Asdf-managed runtimes using Vigilmon — free tier, no credit card required.


Why monitor Asdf-VM managed services?

Asdf is used in local dev, CI, and increasingly in staging and production deployments where teams want strict runtime pinning without Docker overhead. Once those services are running, the standard failure modes apply:

  • Runtime upgrade side effects — a asdf install that pulls a new patch version silently changes behavior or breaks a native extension
  • Plugin installation failures in CI — an Asdf plugin registry outage causes CI to fail to install runtimes, and no service starts at all
  • Process crashes without notification — the Asdf-managed binary exits and the port goes dark with no alert sent
  • Environment isolation gaps — a global shim resolves to the wrong version, causing subtle runtime errors that degrade responses before a full crash

Vigilmon monitors from outside your infrastructure, giving you an objective signal that's independent of what Asdf or the host process thinks is running.


What you'll need

  • A service started with an Asdf-managed runtime that exposes an HTTP or TCP endpoint
  • A free Vigilmon account

Step 1: Add a health endpoint to your service

Give Vigilmon something reliable to check. Add a /health route to the application your Asdf-managed runtime is running.

For a Node.js/Express service (runtime pinned via .tool-versions: nodejs 20.12.0):

app.get('/health', (req, res) => {
  res.json({
    status: 'ok',
    runtime: process.version,
    uptime: process.uptime()
  });
});

For a Python/FastAPI service (runtime pinned via .tool-versions: python 3.12.3):

import sys

@app.get("/health")
def health():
    return {
        "status": "ok",
        "python": sys.version
    }

For a Ruby/Rack service (runtime pinned via .tool-versions: ruby 3.3.1):

get '/health' do
  content_type :json
  { status: 'ok', ruby: RUBY_VERSION }.to_json
end

Including the runtime version in the response makes it easy to confirm which Asdf-pinned version is actually serving traffic — useful when debugging version drift across environments.


Step 2: Verify the runtime before starting the service

Add a startup check to your Makefile or start script to confirm Asdf resolved the correct version before the service boots:

#!/usr/bin/env bash
# start.sh
set -e

EXPECTED_NODE="20.12.0"
ACTUAL_NODE=$(node --version | tr -d 'v')

if [ "$ACTUAL_NODE" != "$EXPECTED_NODE" ]; then
  echo "ERROR: expected Node $EXPECTED_NODE, got $ACTUAL_NODE. Run: asdf install"
  exit 1
fi

node server.js

This prevents a misconfigured Asdf shim from silently running the wrong runtime version in production.


Step 3: Set up HTTP monitoring in Vigilmon

Once your service is running at a publicly reachable URL, point Vigilmon at the health endpoint:

  1. Log in to vigilmon.online and go to Monitors → New Monitor
  2. Choose HTTP / HTTPS
  3. Set the URL to your health endpoint, e.g. https://api.example.com/health
  4. Set the check interval to 1 minute
  5. Under Expected response, set:
    • Status code: 200
    • (Optional) Response body contains: "status":"ok"
  6. Save the monitor

Vigilmon checks from multiple regions every minute. A timeout or non-200 response opens an incident immediately.


Step 4: Add TCP port monitoring for non-HTTP services

Asdf manages runtimes for non-HTTP tools too — database clients, Redis, gRPC servers. Add a TCP monitor for any port your Asdf-managed process binds:

  1. Go to Monitors → New Monitor
  2. Choose TCP Port
  3. Enter your server hostname and port, e.g. db.example.com / 5432
  4. Save

If the Asdf-managed process crashes or the port binding drops, Vigilmon fires an alert within a minute — regardless of what the process supervisor reports.


Step 5: Track key metrics

| Metric | What it catches | |---|---| | HTTP response code | Application crash, bad deploy, wrong runtime version | | HTTP response time | Performance regression from runtime upgrade | | TCP port reachability | Process exit, shim resolution failure | | Response body version field | Silent runtime version mismatch in production |

Vigilmon stores response time history automatically. Set a threshold alert (e.g. alert if response time > 1.5 s) to detect performance regressions from a runtime upgrade before users notice.


Step 6: Instrument CI to monitor runtime installation

Asdf-VM is used heavily in CI to ensure every runner has exactly the right runtimes. When a plugin registry or CDN is down, Asdf silently falls back to cached versions or fails entirely. Add a Vigilmon heartbeat to your CI setup step:

  1. In Vigilmon, go to New Monitor → Heartbeat
  2. Name it CI Runtime Setup — main
  3. Set the expected interval to your CI frequency (e.g. 1 hour for continuous CI, 24 hours for nightly builds)
  4. Copy the ping URL

In your CI workflow (GitHub Actions example):

- name: Set up runtimes with Asdf
  run: |
    asdf plugin add nodejs
    asdf plugin add python
    asdf install
    node --version
    python --version

- name: Ping Vigilmon — runtime setup succeeded
  if: success()
  run: |
    curl -fsS -X POST "${{ secrets.VIGILMON_CI_HEARTBEAT_URL }}" \
      --max-time 10 --retry 3

If Asdf fails to install runtimes and the step errors, no ping is sent and Vigilmon alerts after the grace period.


Step 7: Configure alert channels

  1. Go to Alert Channels → Add Channel
  2. Choose Email or Webhook (Slack, Discord, PagerDuty)
  3. Assign the channel to your HTTP and TCP monitors
  4. Set the alert trigger to 1 failed check for immediate notification

When a service goes down:

🔴 DOWN: api.example.com/health
Duration: 3 minutes
Last response: timeout

When it recovers:

✅ RECOVERED: api.example.com/health
Downtime: 3 minutes

Step 8: Create a status page for your team

If multiple services share Asdf-managed runtimes (e.g. a monorepo with API, worker, and scheduler processes each with their own .tool-versions), a status page surfaces all of them in one view:

  1. Go to Status Pages → New Status Page
  2. Name it (e.g. "Services Status")
  3. Add your HTTP and TCP monitors
  4. Publish and share the URL with your team

Team members can check service health before reporting a bug, and you avoid being paged for self-inflicted outages.


Conclusion

Asdf-VM ensures every developer and CI runner uses exactly the right runtime version. Vigilmon ensures those runtimes are actually serving healthy traffic. Together they close both the "wrong version" and the "service is down" gaps. Set up a /health endpoint, create a one-minute Vigilmon HTTP monitor, and add heartbeat monitoring to your CI runtime-install step — you'll have coverage in under ten minutes.

Get started free at vigilmon.online.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →