Skip to content

orangecoding/pm2-hawkeye

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

33 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

PM2-Hawkeye

Jetbrains Open Source

A modern, real-time web dashboard for your PM2 processes.

Monitor, restart, and tail logs - all from a sleek dark-mode UI.

Node.js License React WebSockets Tests


Features

  • Live process overview - CPU, memory, uptime, and restart count at a glance
  • Real-time log streaming - stdout & stderr tailed directly in the browser
  • Persistent monitoring - CPU/memory history and logs stored in SQLite, survives page reloads
  • One-click restart - restart any process with an inline confirmation
  • PM2 custom actions - trigger any axm_actions your processes expose
  • Secure by default - scrypt password hashing, CSRF protection, rate limiting, CSP headers
  • Single WebSocket connection - no polling, no SSE; all real-time data over one multiplexed stream
  • Alerting - webhook and ntfy notifications when monitored processes log errors, with per-process mute and throttle support
  • Dark-mode UI - clean, responsive dashboard that works on desktop and mobile

Screenshots

Login Main View
Screenshot showing the login page Screenshot showing the main view

πŸ“‘ Live vs. Monitored Processes

PM2-Hawkeye has two modes for each process.

Live only (default)

When you open a process without enabling monitoring, you see real-time CPU, memory, and a live log stream. None of this is saved. Navigating away or closing the tab loses the history - when you return you start fresh.

Monitored

Click Start Monitoring on any process to enable persistent tracking. PM2-Hawkeye will:

  • Sample CPU and memory every 20 seconds and store the history (default: 24 hours)
  • Persist incoming log lines to the database (default: 14 days)
  • Show a sparkline chart of CPU and memory over time
  • Backfill the last log entries from the PM2 log files on first enable

Monitoring state survives server restarts. You can stop monitoring at any time - this removes all stored history for that process.


πŸš€ Quick Start

Prerequisites

  • Node.js 22 or higher
  • PM2 installed globally (npm i -g pm2)
  • At least one PM2 process running

1. Clone & install

git clone https://github.com/orangecoding/pm2-hawkeye.git
cd pm2-hawkeye
yarn install

2. Configure

Copy the example env file and open it in your editor:

cp .env.example .env

Generate a password hash and paste the output into .env:

node -e "
  const crypto = require('crypto');
  const salt = crypto.randomBytes(16).toString('hex');
  const hash = crypto.scryptSync('YOUR_PASSWORD', Buffer.from(salt,'hex'), 64).toString('hex');
  console.log('AUTH_PASSWORD_SALT=' + salt);
  console.log('AUTH_PASSWORD_HASH=' + hash);
"

3. Build & run

npm start

Open http://localhost:3030 in your browser.

4. Run as a PM2 process (recommended)

The recommended production setup is to run PM2-Hawkeye as a PM2 process itself so it is supervised and auto-restarted:

npm run build
pm2 start lib/transport/server.js --name pm2-hawkeye
pm2 save

πŸ”„ Updating

update.sh handles the full update cycle for a self-hosted installation:

./update.sh

It will:

  1. Pull the latest commits from upstream (fast-forward only - aborts if there are local changes)
  2. Install or update Node.js dependencies
  3. Rebuild the frontend bundle
  4. Restart the pm2-hawkeye process under PM2 (if running)

Make the script executable once before first use:

chmod +x update.sh

If PM2-Hawkeye is not running under PM2 when the script finishes, it will print the commands to start it manually.

Note

Database location β€” by default the database is written to ./data/pm2-hawkeye.db inside the project directory. If you update by replacing the project folder (e.g. re-cloning), this file will be lost. Point SQLITE_DB_PATH at a directory outside the project to keep your data safe across updates (pm2-hawkeye.db is created inside it automatically):

SQLITE_DB_PATH=/var/lib/pm2-hawkeye

Create the directory first: mkdir -p /var/lib/pm2-hawkeye

Note

PM2 timestamps β€” PM2-Hawkeye merges stdout and stderr and sorts log lines chronologically. This requires PM2 to prefix each line with a timestamp. Always start your processes with --time:

pm2 start app.js --name my-app --time

Without it, log lines from stdout and stderr cannot be sorted correctly.


βš™οΈ Configuration

All settings are read from a .env file in the project root. Copy .env.example to get started.

Server

Variable Default Description
HOST 0.0.0.0 Bind address
PORT 3030 HTTP and WebSocket port

Authentication

Variable Default Description
AUTH_USERNAME admin Login username (case-insensitive)
AUTH_PASSWORD_SALT - Hex-encoded salt (generated above)
AUTH_PASSWORD_HASH - Hex-encoded scrypt hash (64 bytes)
SESSION_TTL_MS 28800000 Session lifetime in ms (default: 8 h)

Rate limiting

Variable Default Description
AUTH_MIN_RESPONSE_MS 900 Minimum login response time (timing-attack mitigation)
LOGIN_WINDOW_MS 600000 Sliding window for login attempts (10 min)
LOGIN_MAX_REQUESTS 12 Max login attempts per window
LOGIN_FAILURE_WINDOW_MS 1800000 Window for exponential lockout (30 min)
LOGIN_BASE_LOCKOUT_MS 30000 Initial lockout after repeated failures (30 s)
LOGIN_MAX_LOCKOUT_MS 43200000 Maximum lockout period (12 h)
UNAUTH_WINDOW_MS 60000 Window for unauthenticated access attempts (1 min)
UNAUTH_MAX_REQUESTS 10 Max unauthenticated hits before a 5 s penalty
UNAUTH_PENALTY_MS 5000 Delay added to rate-limited unauthenticated responses

Cookies & proxy

Variable Default Description
COOKIE_SECURE auto auto / always / never
TRUST_PROXY 0 Set to 1 when behind a reverse proxy

Storage

Variable Default Description
SQLITE_DB_PATH ./data Directory for the SQLite database (pm2-hawkeye.db is created inside)
METRICS_RETENTION_MS 86400000 How long metric samples are kept (24 h)
LOGS_RETENTION_MS 1209600000 How long log entries are kept (14 days)
MAX_LOG_BYTES_PER_FILE 5242880 Max bytes read per PM2 log file (5 MB)

⚑ Custom Actions with tx2

PM2-Hawkeye can display and trigger custom actions that your app exposes to PM2 via tx2.

Install tx2

npm install tx2

Define actions in your app

import tx2 from 'tx2';

// Simple action
tx2.action('clear cache', (done) => {
  myCache.flush();
  done({ success: true });
});

// Action with a parameter
tx2.action('set log level', (level, done) => {
  logger.setLevel(level);
  done({ level });
});

done() must always be called - it signals to PM2 that the action has completed and sends the return value back to the dashboard.

Trigger from PM2-Hawkeye

Once your process is running, open it in PM2-Hawkeye. Any registered actions appear as buttons in the Actions panel.

Available tx2 APIs

API Purpose
tx2.action(name, fn) Register a triggerable action
tx2.action(name, { arity: 1 }, fn) Action that accepts a parameter
tx2.metric(name, fn) Expose a live metric
tx2.counter(name) Incrementing counter
tx2.histogram(name) Value distribution histogram

Development

PM2-Hawkeye uses a two-process dev setup: the Node.js backend runs on port 3030 and an esbuild dev server handles the frontend on port 3042 with instant rebuilds and hot module replacement.

Start the backend

node --inspect lib/transport/server.js

Start the frontend dev server

npm run dev

Open http://localhost:3042. The dev server proxies all /api/*, /ws/*, and HTML routes through to the backend.

Tests, lint, format

npm test
npm run lint
npm run format        # write
npm run format:check  # check only

πŸ”” Alerting

PM2-Hawkeye can send you a notification whenever a monitored process logs something that matches your configured severity threshold - for example, every time an error is written to stderr.

How it works

Log lines captured from your PM2 processes flow through a detection pipeline:

  1. Level detection - each line is inspected for a severity prefix (ERROR, WARN, INFO, DEBUG). Lines arriving on stderr that carry no detectable prefix are automatically treated as error.
  2. Threshold check - the detected level is compared against the set of levels you selected in Settings. If the level is not in the set, the line is silently discarded.
  3. Per-process mute check - if you have muted a specific process via the megaphone icon (πŸ“’) in the sidebar, alerts for that process are skipped.
  4. Throttle check - in throttle mode a second alert for the same process is suppressed until the configured cool-down window has elapsed. In every match mode all qualifying lines trigger a notification.
  5. Dispatch - all enabled reporters are called concurrently. A failure in one reporter does not block the others.

Settings UI

Click the Settings button in the sidebar toolbar to open the settings overlay.

  • General - edit raw .env key/value pairs and change your login password. Changes are written to disk; a restart of PM2-Hawkeye is required for them to take effect.
  • Alerting - configure the alert mode, log level thresholds, and reporters.

Reporters

Webhook

Sends an HTTP POST request to any URL you choose. You can attach custom request headers and build a fully custom JSON body using key/value pairs with template variables:

Variable Replaced with
{logLevel} Detected log level (error, warn, info, debug)
{log_message} The full log line text
{process_name} The PM2 process name

Variable substitution is JSON-aware: if a value contains {log_message} inside a quoted JSON string it is substituted as a raw string; if it appears as an unquoted JSON value the substituted text is JSON-encoded automatically, preventing malformed payloads.

A live curl preview updates in real time as you fill in the form so you can verify the exact request before saving.

ntfy

Sends a push notification to an ntfy topic. Configure the server URL, topic, message priority, and an optional auth token. PM2-Hawkeye sets the Title, Priority, and Tags headers automatically.

Per-process mute

Every monitored process shows a megaphone icon (πŸ“’) in the sidebar. Click it to mute alerts for that process - the icon dims to indicate the muted state. Click again to re-enable. The preference is stored in the database and survives restarts.


Deploy

PM2-Hawkeye can clone, install, build, and register new Node.js applications directly from the UI -- no manual SSH required.

How it works

Click Deploy in the sidebar toolbar to open the deploy modal. Fill in the form and hit Deploy. PM2-Hawkeye will:

  1. Run an optional pre-setup shell script (e.g. install system dependencies)
  2. git clone the repository into DEPLOY_BASE_DIR/<app-name> (default: ./apps/<app-name>)
  3. Run the install command (npm install, yarn, or pnpm install)
  4. Run an optional build command (e.g. npm run build)
  5. Run an optional post-setup shell script (e.g. run database migrations)
  6. Register and start the process with PM2

A real-time progress log streams each step in the browser.

Deploy form fields

Repository (required)

Field Description
App name Unique PM2 process name. Alphanumeric, dashes, and underscores only.
Repo URL HTTPS URL of a public GitHub or GitLab repository.
Branch Git branch to clone and deploy from. Defaults to main.

Runtime (required)

Field Description
Start script Entry point relative to the repo root, e.g. src/server.js.
Interpreter Node.js interpreter path. Leave as node for the system default.
Exec mode fork (single process) or cluster (multiple workers).
Instances Number of cluster workers. Set -1 to use all CPU cores.

Setup (optional)

Field Description
Install command Package manager command. Select skip to skip dependency installation entirely.
Build command Optional build step, e.g. npm run build.
Pre-setup script Shell script that runs in DEPLOY_BASE_DIR before cloning. Use it to check requirements or install OS packages.
Post-setup script Shell script that runs in the cloned repo directory after the build. Use it for migrations, file permission fixes, etc.

Environment (optional)

Field Description
Env file Path to a .env file inside the repo to load at start time, e.g. .env.production.
Environment variables Key/value pairs passed directly to the process. These override values from the env file.

Additional collapsible sections cover restart behaviour, memory limits, log file paths, file watching, and advanced PM2 options.

Redeploying and editing

Once a process has been deployed through PM2-Hawkeye, an Edit / Redeploy button appears next to it in the sidebar. Clicking it opens the same form pre-filled with the saved configuration.

  • Save changes -- persists the updated configuration without restarting the process.
  • Save & Redeploy -- saves the configuration and immediately triggers a full redeploy: git pull --rebase, reinstall, rebuild, and PM2 restart.

Configuration

Set DEPLOY_BASE_DIR in your .env to control where apps are cloned:

DEPLOY_BASE_DIR=./apps

The directory is created automatically on first deploy. Use an absolute path to place apps outside the project directory.


Security

  • CSRF tokens - one-time-use tokens rotated after every state-changing request
  • Rate limiting - sliding window + exponential backoff on failed logins; separate rate limit for unauthenticated access
  • CSP headers - strict Content-Security-Policy including ws:/wss: for WebSockets
  • Timing-attack mitigation - constant-time credential comparison with a minimum response delay
  • Secure cookies - HttpOnly, SameSite=Strict, optional Secure flag

Sponsorship

I maintain this and other open-source projects in my free time. If you find it useful, consider supporting the project.


License

Apache-2.0 - Β© Christian Kellner

About

Real-time web dashboard for managing PM2 processes. Monitor CPU, memory, and uptime at a glance, stream live logs directly in the browser, restart processes with one click, and trigger custom PM2 actions, all over a single WebSocket connection.

Topics

Resources

License

Stars

Watchers

Forks

Packages