PM2 is the standard process manager for Node.js production deployments, handling clustering, zero-downtime reloads, log management, and automatic process restarts. It gives your Node.js apps resilience — but PM2 can't tell you when an app's upstream endpoint is returning errors, when a process is stuck in a restart loop, or when your SSL certificate is about to expire. Vigilmon fills that gap: monitoring your PM2-managed application endpoints from outside, tracking process health via heartbeats, and alerting on SSL certificate issues before users notice.
What You'll Set Up
- HTTP uptime monitor for PM2-managed application endpoints
- PM2 web dashboard availability check (pm2-web or PM2 Plus)
- Process health monitoring via upstream health endpoints
- Heartbeat monitoring for PM2 process restarts and cron-scheduled jobs
- SSL certificate alerts for managed application domains
Prerequisites
- PM2 2.0+ installed globally (
npm install -g pm2) - At least one Node.js application running under PM2 (
pm2 list) - Applications exposing HTTP endpoints (recommended: a
/healthroute) - A free Vigilmon account
Step 1: Add a Health Endpoint to Your Node.js Application
PM2-managed apps should expose a /health endpoint that Vigilmon can probe. Here are minimal examples for common Node.js frameworks:
Express
app.get('/health', (req, res) => {
res.json({ status: 'ok', uptime: process.uptime(), pid: process.pid });
});
Fastify
fastify.get('/health', async () => {
return { status: 'ok', uptime: process.uptime() };
});
NestJS
@Get('/health')
health(): object {
return { status: 'ok' };
}
The health endpoint should also check internal dependencies (database, Redis, external APIs) and return a non-200 status if they're unavailable:
app.get('/health', async (req, res) => {
try {
await db.query('SELECT 1');
res.json({ status: 'ok' });
} catch (err) {
res.status(503).json({ status: 'error', detail: 'database unavailable' });
}
});
After adding the endpoint, restart the app with PM2:
pm2 restart your-app-name
Step 2: Monitor PM2-Managed Application Endpoints
Add a Vigilmon monitor for each critical PM2-managed application:
- Log in to vigilmon.online and click Add Monitor.
- Set Type to
HTTP / HTTPS. - Enter your application's health URL:
https://yourapp.com/health. - Set Check interval to
1 minute. - Set Expected HTTP status to
200. - Enable Keyword check and enter
"status":"ok"to validate the response body. - Click Save.
Repeat for each PM2-managed application in your pm2 list output.
For clustered applications (PM2 cluster mode), the load balancer IP or domain is the right URL — you're testing the whole cluster, not individual instances.
Step 3: Monitor the PM2 Web Dashboard
If you use pm2-web (an open-source PM2 web UI) or PM2 Plus (the hosted dashboard), add a monitor for the dashboard itself:
pm2-web (self-hosted)
pm2-web runs on port 8080 by default. Install and start it:
npm install -g pm2-web
pm2-web --config pm2-web-config.json
Add a Vigilmon monitor:
- Click Add Monitor → HTTP / HTTPS.
- Set the URL to
http://your-server:8080(or the proxied HTTPS URL). - Set Expected HTTP status to
200. - Set Check interval to
2 minutes. - Click Save.
PM2 Plus (keymetrics.io)
If using PM2 Plus, add a monitor for the PM2 Plus web app at app.pm2.io and check that your linked server appears as connected. This is an external dependency monitoring pattern — you're checking that your PM2 agent can reach the PM2 Plus cloud, not just that the PM2 process is running.
Step 4: SSL Certificate Alerts for Managed Application Domains
PM2-managed Node.js apps commonly serve traffic over HTTPS either via Node.js's built-in TLS or through a reverse proxy (nginx, Caddy, Traefik). Monitor SSL certificates for each application domain:
- Open the HTTPS monitor for each application (created in Step 2).
- Scroll to the SSL certificate section.
- Enable Monitor SSL certificate.
- Set Alert when certificate expires in less than
21 days. - Click Save.
List all domains your PM2 apps serve:
pm2 list
# Note each app name, then check your nginx/proxy config for their domains
Check certificate expiry manually:
echo | openssl s_client -connect yourapp.com:443 2>/dev/null \
| openssl x509 -noout -enddate
Add a separate Vigilmon SSL monitor for each domain, especially for apps with custom domains not on wildcard certificates.
Step 5: Heartbeat Monitoring for PM2 Process Restarts
PM2 restarts processes automatically on crash — but a process stuck in a restart loop (status: errored cycling to online) is doing no useful work. Use a cron heartbeat that only pings Vigilmon when the app is healthy, not just running:
Create the heartbeat monitor:
- In Vigilmon, click Add Monitor → Cron Heartbeat.
- Set the name to your app name (e.g.,
api-server). - Set Expected ping interval to
2 minutes. - Copy the heartbeat URL (e.g.
https://vigilmon.online/heartbeat/abc123).
Add a PM2 ecosystem health script:
Create /usr/local/bin/pm2-heartbeat.sh:
#!/bin/bash
APP_NAME="your-app-name"
HEARTBEAT_URL="https://vigilmon.online/heartbeat/abc123"
# Only ping if the app is online (not errored/stopped)
STATUS=$(pm2 jlist 2>/dev/null | node -e "
const apps = JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf8'));
const app = apps.find(a => a.name === '${APP_NAME}');
console.log(app ? app.pm2_env.status : 'not_found');
")
if [ "$STATUS" = "online" ]; then
curl -s "$HEARTBEAT_URL" --max-time 5
fi
chmod +x /usr/local/bin/pm2-heartbeat.sh
Add to crontab:
* * * * * /usr/local/bin/pm2-heartbeat.sh
Alternative: ping from the application on each request cycle:
For cron-scheduled PM2 jobs (apps with cron_restart in their ecosystem config), ping from the app after each successful run:
const https = require('https');
async function runJob() {
await processQueue();
// Confirm successful run to Vigilmon
https.get('https://vigilmon.online/heartbeat/abc123').on('error', () => {});
}
This catches the case where PM2 restarts the process successfully but the application logic is failing — a silent failure that PM2's process manager won't detect.
Step 6: Configure Alert Channels
- Go to Alert Channels in Vigilmon and add Slack, email, PagerDuty, or a webhook.
- Group all monitors for a server in a Vigilmon project.
- Set Consecutive failures before alert to
2on application endpoint monitors — PM2 zero-downtime reloads cause brief gaps. - Set Consecutive failures before alert to
1on heartbeat monitors. - Enable Recovery notifications so you know when PM2 brings an app back online.
For high-traffic production apps, set the check interval to 30 seconds for the /health endpoint monitor.
Summary
| Monitor | Target | What It Catches |
|---|---|---|
| App health endpoint | https://yourapp.com/health | App errors, dependency failures |
| PM2 web dashboard | http://server:8080 | Dashboard/monitoring UI down |
| SSL certificate | Each app domain | Certificate expiry |
| Cron heartbeat | Vigilmon heartbeat URL | Restart loop, logic failure |
PM2 makes Node.js applications resilient to process crashes — but it can't detect upstream dependency failures, restart loops, or application-level logic errors. With Vigilmon monitoring each application's health endpoint from outside the server, tracking SSL certificates, and receiving heartbeats only when apps are genuinely healthy, you get the production-grade observability layer that PM2's built-in tools don't provide.