Skip to main content

Monitor any command with periodic Slack, Discord, or email notifications

Project description

Job Monitor

A CLI tool that wraps any command (or attaches to a running process) and sends periodic notifications with job status, system resource usage, and recent terminal output. Supports Slack, Discord, and email backends.

Installation

From PyPI

pip install jobmonitor-cli

From source

# Create the conda environment
conda env create -f environment.yml

# Install the package
conda activate jobmonitor
pip install -e .

# (Optional) Make available system-wide for all users
sudo ln -s $(which jobmonitor) /usr/local/bin/jobmonitor

Backend Setup

You can configure backends via CLI flags, environment variables, or a config file (~/.jobmonitorrc). Priority: CLI flags > env vars > config file > defaults.

Slack (default)

  1. Go to api.slack.com/apps > Create New App > From scratch
  2. Go to Incoming Webhooks > Toggle On > Add New Webhook to Workspace
  3. Pick a channel and copy the webhook URL
  4. Add to your ~/.bashrc:
export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"

Discord

  1. In your Discord server, go to a channel's settings > Integrations > Webhooks > New Webhook
  2. Copy the webhook URL
  3. Add to your ~/.bashrc:
export DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/YOUR/WEBHOOK/URL"

Email

Email uses SMTP to send notifications. If your machine has postfix or sendmail running, it works out of the box with localhost.

Add to your ~/.bashrc:

export JOBMONITOR_EMAIL_TO="you@example.com"
# Optional — defaults shown:
# export SMTP_SERVER="localhost"

For external SMTP (e.g., Gmail), set --smtp-server and --smtp-port flags. Note: Gmail requires an app password.

Changing the default backend

By default, jobmonitor uses Slack. To change the default, add to your ~/.bashrc:

export JOBMONITOR_BACKEND="discord"   # or "email"

You can always override per-invocation with --backend.

Config File

Instead of environment variables, you can create ~/.jobmonitorrc to set persistent defaults:

[defaults]
backend = slack
interval = 2h
tail = 5
cpu = false
disk = false
no-gpu = false
no-ram = false

[slack]
webhook_url = https://hooks.slack.com/services/YOUR/WEBHOOK/URL

[discord]
webhook_url = https://discord.com/api/webhooks/YOUR/WEBHOOK/URL

[email]
to = you@example.com
from = jobmonitor@yourmachine
smtp_server = localhost
smtp_port = 25

All sections and keys are optional. CLI flags and environment variables always take priority over the config file.

Usage

Wrap a new command

jobmonitor --interval 2h --name "experiment-1" -- python train.py --epochs 100
jobmonitor --interval 1h --name "full-sweep" -- bash experiments.sh

# Tail a log file instead of stdout
jobmonitor --interval 2h --log path/to/logfile.log -- python train.py

# Using Discord
jobmonitor --backend discord --interval 2h -- python train.py

# Using email
jobmonitor --backend email --email-to user@example.com -- python train.py

Attach to an already-running process

# Find the PID
ps aux | grep train

# Attach to it
jobmonitor --pid 12345 --interval 2h --name "experiment-1"

# Optionally tail a log file for output context
jobmonitor --pid 12345 --interval 2h --log path/to/logfile.log

Options

Flag Default Description
--interval 2h Notification interval (e.g. 30m, 1h30m, 2h)
--backend slack Notification backend: slack, discord, or email
--webhook-url config/env Webhook URL for Slack or Discord
--name auto Job name shown in notifications
--tail 5 Number of recent output lines to include
--pid - Attach to an existing process by PID
--log - Log file to tail for notification output instead of stdout. Works in both wrap and --pid modes
--no-gpu - Skip GPU info in notifications
--no-ram - Skip RAM info in notifications
--cpu - Include CPU usage in notifications
--disk - Include disk usage in notifications
--email-to config/env Recipient email (email backend)
--email-from user@hostname Sender email (email backend)
--smtp-server localhost SMTP server (email backend)
--smtp-port 25 SMTP port (email backend)

Notifications

Each notification includes:

  • Job status (started / running / completed / failed / cancelled)
  • Elapsed time
  • Hostname
  • RAM usage (unless --no-ram)
  • GPU utilization, memory, and temperature (unless --no-gpu)
  • CPU usage (opt-in with --cpu)
  • Disk usage (opt-in with --disk)
  • Last N lines of terminal output (or log file if --log is set)
  • The command being monitored

A notification is sent immediately when monitoring begins, then at every --interval, and once more when the job finishes.

Running tests

conda activate jobmonitor
pytest tests/ -v

Publishing to PyPI

pip install build twine
python -m build
twine upload dist/*

Requires a PyPI account and API token.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jobmonitor_cli-0.1.2.tar.gz (16.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jobmonitor_cli-0.1.2-py3-none-any.whl (11.4 kB view details)

Uploaded Python 3

File details

Details for the file jobmonitor_cli-0.1.2.tar.gz.

File metadata

  • Download URL: jobmonitor_cli-0.1.2.tar.gz
  • Upload date:
  • Size: 16.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.20

File hashes

Hashes for jobmonitor_cli-0.1.2.tar.gz
Algorithm Hash digest
SHA256 8971db460fe36fc243ae91686c19723c4a9957816143168643c23ec646726745
MD5 83bfa1893097ac4844731ca91684706a
BLAKE2b-256 5e3137ff65acdb1237dbfcb9aec89dffb19c1e310864043d2467901f0c1ec8b2

See more details on using hashes here.

File details

Details for the file jobmonitor_cli-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: jobmonitor_cli-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 11.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.20

File hashes

Hashes for jobmonitor_cli-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 e861202b62af2eb8351312f724062e69fc58477b20a83002a092dd9770aaef47
MD5 431e47436525f418c93abe343e4ecc37
BLAKE2b-256 491f418a4fb9f60c2225632600e9c3f379082c669e15c2f1ba9047734aee9905

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page