One command to see what is going on with your Linux server right now.
Project description
wtftools
One command to see what is going on with your Linux server right now.
English | Español | Português | Français | Deutsch | Italiano | Русский | 中文 | 日本語 | हिन्दी | 한국어
You log in to a server and something feels wrong. Instead of running ten
commands (htop, df -h, journalctl, systemctl --failed, …) you run one:
$ wtf
─────────── AUDIT ────────────
[ OK ] uptime 3d 4h 12m
[ OK ] load average 0.42 0.51 0.55 / 8 CPU
[ OK ] memory 4.1GB / 16.0GB used (25%)
[WARN] disk /var 17.0GB / 20.0GB used (85%)
[ OK ] zombie processes 0 zombies
[FAIL] failed systemd units 1 failed unit(s)
[ OK ] crontab syntax 14 cron line(s), no errors
Summary: 12 ok · 1 warn · 1 fail · 2 skip
Green is fine, yellow needs a look, red needs fixing. That's it.
Install
pipx install wtftools # recommended — works on any modern distro
No pipx? Any of these works too:
pip install wtftools # classic pip (core, no dependencies)
pip install wtftools[full] # + psutil for richer process/socket info
sudo dpkg -i wtftools_*.deb # Debian/Ubuntu package (see Releases)
After install you have the wtf command. Try it: wtf.
The commands you will actually use
wtf # full health check — start here
wtf problems # show ONLY what is wrong (warnings + failures)
wtf explain # what to do about each problem, step by step
Then ask about one resource at a time, like show commands on a switch:
wtf disk # is there space? per-mount usage, inodes, read-only
wtf disk --tree # WHAT is eating the space (largest directories)
wtf cpu # load, iowait, top CPU consumers
wtf mem # RAM/swap, OOM kills, top memory consumers
wtf net # interfaces, IPs, gateway, DNS, listening ports
wtf io # disk read/write rates, IO-stuck processes
wtf who # who is logged in, recent logins, failed auth
Example — disk is filling up, find the culprit:
$ wtf disk --tree /var
────────────── DISK ──────────────
/ [████████████████····] 79% 1.4TB / 1.8TB ext4
/var [█████████████████···] 85% 17.0GB / 20.0GB ext4
───────── LARGEST UNDER /var ─────────
15.0GB /var/lib
3.1GB /var/log
1.8GB /var/log/app
wtf disk --tree without a path picks the fullest mount automatically.
Learning Linux? Add --show-commands to any resource command and it also
prints the classic commands it replaces, so you can run them yourself:
$ wtf cpu --show-commands
...
equivalent commands:
$ uptime
$ top -bn1 | head
$ ps aux --sort=-%cpu | head
When something is broken
wtf problems -v # every problem, with detail
wtf events --since 6 # timeline: reboots, OOM kills, failed units
wtf service nginx # one service: state, restarts, ports, journal
wtf logs --since '2 hours ago' # recent ERROR+ journal entries by service
wtf explain # actionable advice per finding
wtf explain --llm ollama # or let a local LLM summarize it
Output for scripts: grep, awk, jq
Colors disappear automatically when you pipe, so plain grep always works.
Every command also has machine-readable formats — plain (tab-separated,
no headers) and json. The flag works before the subcommand too:
wtf -f json disk # same as: wtf disk --format json
wtf disk --format plain # tab-separated, no headers
wtf disk --format json | jq . # full JSON
# mounts above 80%:
wtf disk --format json | jq -r '.mounts[] | select(.percent > 80) | .target'
# failed checks only, names column:
wtf audit --format plain | awk -F'\t' '$1 == "fail" {print $2}'
# top directory eating /var, bytes and path:
wtf disk --tree /var --format plain | awk -F'\t' '$1 == "tree" {print $2, $3; exit}'
JSON payloads of the resource commands carry schema_version so your
scripts survive upgrades.
Daily routine and monitoring
One command for the morning check — audit, what changed since the last run, and the event timeline, with a one-line verdict on top:
wtf daily # audit + diff vs yesterday + events
It saves a snapshot on every run, so tomorrow's wtf daily shows the diff.
A crontab line for unattended use (mails only when something is wrong):
0 8 * * * wtf daily --format json > /var/log/wtf-daily.json 2>&1 || mail -s "wtf $(hostname)" you@example.com < /var/log/wtf-daily.json
The building blocks are also available separately:
wtf audit --brief # one line — perfect for MOTD / SSH banner
wtf audit --save # save a snapshot
wtf diff # what changed since the last snapshot
wtf history # list saved snapshots
# cron alerting without any monitoring stack:
wtf audit --alert 'mail -s "wtf $WTF_HOST" you@example.com'
wtf audit --alert-on warn --alert 'curl -X POST $SLACK_WEBHOOK -d @-'
Exit codes are CI/cron-friendly:
| code | meaning |
|---|---|
| 0 | everything OK |
| 1 | warnings with --strict, or crontab errors |
| 2 | audit found a [FAIL] |
| 130 | interrupted (Ctrl-C) |
All subcommands
| command | what it does |
|---|---|
wtf / wtf audit |
green/yellow/red checklist: what is OK and what is not |
wtf problems |
only WARN+FAIL rows |
wtf daily |
morning check: audit + diff vs last run + events |
wtf explain |
per-check actionable advice; --llm to pipe to an LLM |
wtf disk |
per-mount usage; --tree shows largest directories |
wtf cpu |
load, iowait, pressure, top CPU consumers |
wtf mem |
RAM/swap, OOM kills, top memory consumers |
wtf net |
interfaces, gateway, DNS, errors, listening ports |
wtf io |
per-device IO rates, pressure, stuck processes |
wtf who |
logged-in users, recent logins, failed auth |
wtf info |
one-page snapshot: all of the above at once |
wtf top |
focused process top: sort by cpu/rss, filter user/name |
wtf ports |
listening sockets with owning PID/user/command |
wtf service NAME |
drilldown one service: state, restarts, mem, ports, journal |
wtf logs |
recent ERROR+ journal entries grouped by service |
wtf events |
chronological timeline: reboots, OOM, failed units, … |
wtf history |
list saved audit snapshots (wtf audit --save to create) |
wtf diff |
compare current state to a saved snapshot |
wtf crontab |
validate all standard crontab locations + per-user crontabs |
wtf doctor |
self-diagnostic: which tools wtftools can actually use |
wtf config |
show effective config / print example |
wtftools absorbs and supersedes
checkcrontab — the same cron
validator now lives at wtf crontab.
Advanced audit options
wtf audit -v # show extra detail (failed units, OOM events)
wtf audit --strict # exit 1 on warnings (CI-friendly)
wtf audit --check memory --check disks # run named checks only
wtf audit --list-checks # show all available check short-names
wtf audit --since 1 # look-back window for OOM/auth/kernel (default 24h)
wtf audit --ignore swap --ignore "disk /mnt/Backup" # silence checks
wtf audit --format csv > audit.csv # spreadsheet-friendly
wtf audit --format html -o report.html # self-contained HTML for tickets
wtf audit --format prometheus # metrics for node_exporter textfile
Built-in checks
uptime · system state · load average · CPU iowait · PSI cpu/memory/io · TCP retransmits · memory · swap · disk (per mount) · inodes · read-only mounts · failed systemd units · enabled-but-down services · restart loops · network errors · conntrack · journal disk usage · zombies · D-state processes · OOM kills · kernel errors · kernel taint · cert expiry · open file descriptors · process count · failed auth · time sync · pending updates · reboot required · cron daemon · crontab syntax · docker · hw temperatures · disk SMART · DNS · HTTP/TCP probes · fail2ban.
Config
Thresholds and ignores live in an INI file at any of:
/etc/wtftools/config.ini/etc/wtf/config.ini~/.config/wtftools/config.ini
Run wtf config --example for a fully-commented template. Headlines:
[thresholds]
disk_warn = 85
disk_fail = 95
swap_warn = 50
swap_fail = 90
[ignore]
checks = swap, updates
result_names =
disk /mnt/Backup
Compatibility
- Python 3.8+
- Linux (systemd distributions are the happy path; the tool degrades
gracefully when
systemctl/journalctl/psutilare missing) - No network access required for the core CLI
- Optional network:
wtf explain --llm claude/openai,wtf doctor --check-updates
From source
git clone https://github.com/wachawo/wtftools
cd wtftools
pip install -e .
# or test without installing:
python3 wtf.py audit
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wtftools-0.0.1.tar.gz.
File metadata
- Download URL: wtftools-0.0.1.tar.gz
- Upload date:
- Size: 124.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
07a93f1dcc6f4b54b22b8ed56491c32fbc105b526af4a5ecab900729bc242782
|
|
| MD5 |
bca8a4ef1afd542b2c62ed053fa7c21c
|
|
| BLAKE2b-256 |
62f8caac7233bfe8194a53bb6c660dab8b8627b7f6fc91d531c9f3d52981fa05
|
Provenance
The following attestation bundles were made for wtftools-0.0.1.tar.gz:
Publisher:
publish.yml on wachawo/wtftools
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wtftools-0.0.1.tar.gz -
Subject digest:
07a93f1dcc6f4b54b22b8ed56491c32fbc105b526af4a5ecab900729bc242782 - Sigstore transparency entry: 1820105195
- Sigstore integration time:
-
Permalink:
wachawo/wtftools@2449a7035f1cc25fbccede962320c91bcc7fe667 -
Branch / Tag:
refs/tags/0.0.1 - Owner: https://github.com/wachawo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2449a7035f1cc25fbccede962320c91bcc7fe667 -
Trigger Event:
push
-
Statement type:
File details
Details for the file wtftools-0.0.1-py3-none-any.whl.
File metadata
- Download URL: wtftools-0.0.1-py3-none-any.whl
- Upload date:
- Size: 77.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
435b22f95f6352e9b6fef08aa10709fc1719083700663c8d7e466344f1d27690
|
|
| MD5 |
cd7ff6a0328aeeaa93fa2ebc40e72441
|
|
| BLAKE2b-256 |
e41cece7f53f0af903dcd8e2473d5deea5aeebbb8cca50df324f36118eb84889
|
Provenance
The following attestation bundles were made for wtftools-0.0.1-py3-none-any.whl:
Publisher:
publish.yml on wachawo/wtftools
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wtftools-0.0.1-py3-none-any.whl -
Subject digest:
435b22f95f6352e9b6fef08aa10709fc1719083700663c8d7e466344f1d27690 - Sigstore transparency entry: 1820105205
- Sigstore integration time:
-
Permalink:
wachawo/wtftools@2449a7035f1cc25fbccede962320c91bcc7fe667 -
Branch / Tag:
refs/tags/0.0.1 - Owner: https://github.com/wachawo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2449a7035f1cc25fbccede962320c91bcc7fe667 -
Trigger Event:
push
-
Statement type: