wtftools 0.0.0__tar.gz → 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {wtftools-0.0.0 → wtftools-0.0.1}/CHANGELOG.md +43 -0
- wtftools-0.0.1/PKG-INFO +307 -0
- wtftools-0.0.1/README.md +267 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/pyproject.toml +4 -4
- wtftools-0.0.1/scripts/build-deb.sh +63 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/scripts/wtf.bash-completion +28 -8
- {wtftools-0.0.0 → wtftools-0.0.1}/tests/test_iteration7.py +17 -1
- wtftools-0.0.1/tests/test_plain_formats.py +203 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/wtftools/info.py +36 -6
- {wtftools-0.0.0 → wtftools-0.0.1}/wtftools/main.py +286 -41
- wtftools-0.0.1/wtftools/sections.py +375 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/wtftools/sysinfo.py +124 -0
- wtftools-0.0.1/wtftools.egg-info/PKG-INFO +307 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/wtftools.egg-info/SOURCES.txt +2 -0
- wtftools-0.0.0/PKG-INFO +0 -246
- wtftools-0.0.0/README.md +0 -184
- wtftools-0.0.0/scripts/build-deb.sh +0 -33
- wtftools-0.0.0/wtftools.egg-info/PKG-INFO +0 -246
- {wtftools-0.0.0 → wtftools-0.0.1}/LICENSE +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/MANIFEST.in +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/setup.cfg +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/tests/test_audit.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/tests/test_audit_extras.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/tests/test_colors.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/tests/test_config.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/tests/test_cron.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/tests/test_explain_deep.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/tests/test_info.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/tests/test_iteration10.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/tests/test_iteration2_extras.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/tests/test_iteration3.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/tests/test_iteration4.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/tests/test_iteration5.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/tests/test_iteration6.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/tests/test_iteration8.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/tests/test_main.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/tests/test_main_extras.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/tests/test_public_api.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/tests/test_sysinfo.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/wtftools/__init__.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/wtftools/__main__.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/wtftools/audit.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/wtftools/colors.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/wtftools/config.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/wtftools/cron.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/wtftools/events.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/wtftools/explain.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/wtftools/llm.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/wtftools/snapshot.py +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/wtftools.egg-info/dependency_links.txt +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/wtftools.egg-info/entry_points.txt +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/wtftools.egg-info/requires.txt +0 -0
- {wtftools-0.0.0 → wtftools-0.0.1}/wtftools.egg-info/top_level.txt +0 -0
|
@@ -6,6 +6,49 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.0.1] - 2026-06-14
|
|
10
|
+
|
|
11
|
+
### Added — per-resource subcommands
|
|
12
|
+
- `wtf disk` — per-mount usage with inode percent and read-only flags;
|
|
13
|
+
`--tree [PATH]` lists the largest directories (du-based, `--depth`,
|
|
14
|
+
`--top`); without PATH it picks the fullest mount automatically.
|
|
15
|
+
- `wtf cpu` — model, loadavg (+per-cpu), iowait, PSI, top-5 by CPU.
|
|
16
|
+
- `wtf mem` — RAM/swap, PSI, OOM kills in the look-back window, top-5 by RSS.
|
|
17
|
+
- `wtf net` — interfaces, default gateway, DNS servers, interface error
|
|
18
|
+
counters, listening TCP ports summary.
|
|
19
|
+
- `wtf io` — PSI io, iowait, per-device read/write rates and utilization
|
|
20
|
+
(sampled from `/proc/diskstats`), D-state processes.
|
|
21
|
+
- `wtf who` — logged-in users, recent logins, failed-auth count.
|
|
22
|
+
- All six support `--format text|plain|json`; `plain` is tab-separated for
|
|
23
|
+
awk/grep, JSON includes `schema_version`.
|
|
24
|
+
- New module `wtftools/sections.py`; new sysinfo helpers:
|
|
25
|
+
`get_default_gateway`, `get_dns_servers`, `get_logged_in_users`,
|
|
26
|
+
`get_du_tree`, `get_disk_io_per_device`.
|
|
27
|
+
|
|
28
|
+
### Added — teaching mode
|
|
29
|
+
- `--show-commands` on `disk`/`cpu`/`mem`/`net`/`io`/`who` prints the
|
|
30
|
+
classic commands each view replaces (`df -h`, `ss -tlnp`, …), so the
|
|
31
|
+
output can be learned from and double-checked by hand.
|
|
32
|
+
|
|
33
|
+
### Added — daily routine and pipeline output
|
|
34
|
+
- `wtf daily` — the morning check as one command: one-line verdict, diff
|
|
35
|
+
vs the previous snapshot, event timeline and the full audit; saves a
|
|
36
|
+
snapshot on every run so the next day diffs against it.
|
|
37
|
+
- `--format plain` for `top`, `ports`, `events`, `logs`, `services` and
|
|
38
|
+
`info` — every command now has a tab-separated twin for grep/awk.
|
|
39
|
+
- Global `-f/--format` flag: `wtf -f json disk` works; a `--format` given
|
|
40
|
+
after the subcommand still wins.
|
|
41
|
+
- `schema_version` added to the JSON payloads of `info`, `events`, `logs`,
|
|
42
|
+
`services` and `daily`.
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
- `wtf ports` no longer fails without psutil — it falls back to an
|
|
46
|
+
`ss`-based TCP listing (no PID/user info; UDP still needs psutil).
|
|
47
|
+
- `wtf service` is now an alias for `wtf services`.
|
|
48
|
+
- README restructured for first-time users: install + the most-used
|
|
49
|
+
commands up top, scripting (grep/awk/jq) cookbook, advanced flags below.
|
|
50
|
+
- Bash completion covers the new subcommands.
|
|
51
|
+
|
|
9
52
|
### Removed — plugin infrastructure
|
|
10
53
|
- `wtftools/plugin_sdk.py` — Python helper for plugin authors.
|
|
11
54
|
- `wtftools/checks/plugins.py` — discovery / executor / parser for
|
wtftools-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: wtftools
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: One command to see what is going on with your Linux server right now.
|
|
5
|
+
Author-email: Aleksandr Pimenov <wachawo@gmail.com>
|
|
6
|
+
Maintainer-email: Aleksandr Pimenov <wachawo@gmail.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/wachawo/wtftools
|
|
9
|
+
Project-URL: Repository, https://github.com/wachawo/wtftools.git
|
|
10
|
+
Project-URL: Documentation, https://github.com/wachawo/wtftools#readme
|
|
11
|
+
Project-URL: Bug Reports, https://github.com/wachawo/wtftools/issues
|
|
12
|
+
Keywords: devops,sre,linux,diagnostics,monitoring,cron,system,audit,cli
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: System Administrators
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
23
|
+
Classifier: Topic :: System :: Systems Administration
|
|
24
|
+
Classifier: Topic :: System :: Monitoring
|
|
25
|
+
Classifier: Topic :: Utilities
|
|
26
|
+
Requires-Python: >=3.8
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Provides-Extra: full
|
|
30
|
+
Requires-Dist: psutil>=5.9.0; extra == "full"
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
33
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
34
|
+
Requires-Dist: coverage>=7.0.0; extra == "dev"
|
|
35
|
+
Requires-Dist: ruff>=0.4.0; extra == "dev"
|
|
36
|
+
Requires-Dist: build>=1.0.0; extra == "dev"
|
|
37
|
+
Requires-Dist: stdeb>=0.10.0; extra == "dev"
|
|
38
|
+
Requires-Dist: pre-commit>=3.0.0; extra == "dev"
|
|
39
|
+
Dynamic: license-file
|
|
40
|
+
|
|
41
|
+
# wtftools
|
|
42
|
+
|
|
43
|
+
[](https://github.com/wachawo/wtftools/actions/workflows/ci.yml)
|
|
44
|
+
[](https://pypi.org/project/wtftools/)
|
|
45
|
+
[](https://pypi.org/project/wtftools/)
|
|
46
|
+
[](https://github.com/wachawo/wtftools/blob/main/LICENSE)
|
|
47
|
+
[](https://pypi.org/project/wtftools/)
|
|
48
|
+
|
|
49
|
+
> One command to see what is going on with your Linux server right now.
|
|
50
|
+
|
|
51
|
+
**English** | [Español](https://github.com/wachawo/wtftools/blob/main/docs/README_ES.md) | [Português](https://github.com/wachawo/wtftools/blob/main/docs/README_PT.md) | [Français](https://github.com/wachawo/wtftools/blob/main/docs/README_FR.md) | [Deutsch](https://github.com/wachawo/wtftools/blob/main/docs/README_DE.md) | [Italiano](https://github.com/wachawo/wtftools/blob/main/docs/README_IT.md) | [Русский](https://github.com/wachawo/wtftools/blob/main/docs/README_RU.md) | [中文](https://github.com/wachawo/wtftools/blob/main/docs/README_ZH.md) | [日本語](https://github.com/wachawo/wtftools/blob/main/docs/README_JA.md) | [हिन्दी](https://github.com/wachawo/wtftools/blob/main/docs/README_HI.md) | [한국어](https://github.com/wachawo/wtftools/blob/main/docs/README_KR.md)
|
|
52
|
+
|
|
53
|
+
You log in to a server and something feels wrong. Instead of running ten
|
|
54
|
+
commands (`htop`, `df -h`, `journalctl`, `systemctl --failed`, …) you run one:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
$ wtf
|
|
58
|
+
─────────── AUDIT ────────────
|
|
59
|
+
[ OK ] uptime 3d 4h 12m
|
|
60
|
+
[ OK ] load average 0.42 0.51 0.55 / 8 CPU
|
|
61
|
+
[ OK ] memory 4.1GB / 16.0GB used (25%)
|
|
62
|
+
[WARN] disk /var 17.0GB / 20.0GB used (85%)
|
|
63
|
+
[ OK ] zombie processes 0 zombies
|
|
64
|
+
[FAIL] failed systemd units 1 failed unit(s)
|
|
65
|
+
[ OK ] crontab syntax 14 cron line(s), no errors
|
|
66
|
+
|
|
67
|
+
Summary: 12 ok · 1 warn · 1 fail · 2 skip
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Green is fine, yellow needs a look, red needs fixing. That's it.
|
|
71
|
+
|
|
72
|
+
## Install
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
pipx install wtftools # recommended — works on any modern distro
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
No `pipx`? Any of these works too:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pip install wtftools # classic pip (core, no dependencies)
|
|
82
|
+
pip install wtftools[full] # + psutil for richer process/socket info
|
|
83
|
+
sudo dpkg -i wtftools_*.deb # Debian/Ubuntu package (see Releases)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
After install you have the `wtf` command. Try it: `wtf`.
|
|
87
|
+
|
|
88
|
+
## The commands you will actually use
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
wtf # full health check — start here
|
|
92
|
+
wtf problems # show ONLY what is wrong (warnings + failures)
|
|
93
|
+
wtf explain # what to do about each problem, step by step
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Then ask about one resource at a time, like `show` commands on a switch:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
wtf disk # is there space? per-mount usage, inodes, read-only
|
|
100
|
+
wtf disk --tree # WHAT is eating the space (largest directories)
|
|
101
|
+
wtf cpu # load, iowait, top CPU consumers
|
|
102
|
+
wtf mem # RAM/swap, OOM kills, top memory consumers
|
|
103
|
+
wtf net # interfaces, IPs, gateway, DNS, listening ports
|
|
104
|
+
wtf io # disk read/write rates, IO-stuck processes
|
|
105
|
+
wtf who # who is logged in, recent logins, failed auth
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Example — disk is filling up, find the culprit:
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
$ wtf disk --tree /var
|
|
112
|
+
────────────── DISK ──────────────
|
|
113
|
+
/ [████████████████····] 79% 1.4TB / 1.8TB ext4
|
|
114
|
+
/var [█████████████████···] 85% 17.0GB / 20.0GB ext4
|
|
115
|
+
|
|
116
|
+
───────── LARGEST UNDER /var ─────────
|
|
117
|
+
15.0GB /var/lib
|
|
118
|
+
3.1GB /var/log
|
|
119
|
+
1.8GB /var/log/app
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`wtf disk --tree` without a path picks the fullest mount automatically.
|
|
123
|
+
|
|
124
|
+
Learning Linux? Add `--show-commands` to any resource command and it also
|
|
125
|
+
prints the classic commands it replaces, so you can run them yourself:
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
$ wtf cpu --show-commands
|
|
129
|
+
...
|
|
130
|
+
equivalent commands:
|
|
131
|
+
$ uptime
|
|
132
|
+
$ top -bn1 | head
|
|
133
|
+
$ ps aux --sort=-%cpu | head
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## When something is broken
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
wtf problems -v # every problem, with detail
|
|
140
|
+
wtf events --since 6 # timeline: reboots, OOM kills, failed units
|
|
141
|
+
wtf service nginx # one service: state, restarts, ports, journal
|
|
142
|
+
wtf logs --since '2 hours ago' # recent ERROR+ journal entries by service
|
|
143
|
+
wtf explain # actionable advice per finding
|
|
144
|
+
wtf explain --llm ollama # or let a local LLM summarize it
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Output for scripts: grep, awk, jq
|
|
148
|
+
|
|
149
|
+
Colors disappear automatically when you pipe, so plain `grep` always works.
|
|
150
|
+
Every command also has machine-readable formats — `plain` (tab-separated,
|
|
151
|
+
no headers) and `json`. The flag works before the subcommand too:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
wtf -f json disk # same as: wtf disk --format json
|
|
155
|
+
wtf disk --format plain # tab-separated, no headers
|
|
156
|
+
wtf disk --format json | jq . # full JSON
|
|
157
|
+
|
|
158
|
+
# mounts above 80%:
|
|
159
|
+
wtf disk --format json | jq -r '.mounts[] | select(.percent > 80) | .target'
|
|
160
|
+
|
|
161
|
+
# failed checks only, names column:
|
|
162
|
+
wtf audit --format plain | awk -F'\t' '$1 == "fail" {print $2}'
|
|
163
|
+
|
|
164
|
+
# top directory eating /var, bytes and path:
|
|
165
|
+
wtf disk --tree /var --format plain | awk -F'\t' '$1 == "tree" {print $2, $3; exit}'
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
JSON payloads of the resource commands carry `schema_version` so your
|
|
169
|
+
scripts survive upgrades.
|
|
170
|
+
|
|
171
|
+
## Daily routine and monitoring
|
|
172
|
+
|
|
173
|
+
One command for the morning check — audit, what changed since the last run,
|
|
174
|
+
and the event timeline, with a one-line verdict on top:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
wtf daily # audit + diff vs yesterday + events
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
It saves a snapshot on every run, so tomorrow's `wtf daily` shows the diff.
|
|
181
|
+
A crontab line for unattended use (mails only when something is wrong):
|
|
182
|
+
|
|
183
|
+
```cron
|
|
184
|
+
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
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
The building blocks are also available separately:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
wtf audit --brief # one line — perfect for MOTD / SSH banner
|
|
191
|
+
wtf audit --save # save a snapshot
|
|
192
|
+
wtf diff # what changed since the last snapshot
|
|
193
|
+
wtf history # list saved snapshots
|
|
194
|
+
|
|
195
|
+
# cron alerting without any monitoring stack:
|
|
196
|
+
wtf audit --alert 'mail -s "wtf $WTF_HOST" you@example.com'
|
|
197
|
+
wtf audit --alert-on warn --alert 'curl -X POST $SLACK_WEBHOOK -d @-'
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Exit codes are CI/cron-friendly:
|
|
201
|
+
|
|
202
|
+
| code | meaning |
|
|
203
|
+
|------|--------------------------------------------------|
|
|
204
|
+
| 0 | everything OK |
|
|
205
|
+
| 1 | warnings with `--strict`, or crontab errors |
|
|
206
|
+
| 2 | audit found a `[FAIL]` |
|
|
207
|
+
| 130 | interrupted (Ctrl-C) |
|
|
208
|
+
|
|
209
|
+
## All subcommands
|
|
210
|
+
|
|
211
|
+
| command | what it does |
|
|
212
|
+
|---------------------|-------------------------------------------------------------|
|
|
213
|
+
| `wtf` / `wtf audit` | green/yellow/red checklist: what is OK and what is not |
|
|
214
|
+
| `wtf problems` | only WARN+FAIL rows |
|
|
215
|
+
| `wtf daily` | morning check: audit + diff vs last run + events |
|
|
216
|
+
| `wtf explain` | per-check actionable advice; `--llm` to pipe to an LLM |
|
|
217
|
+
| `wtf disk` | per-mount usage; `--tree` shows largest directories |
|
|
218
|
+
| `wtf cpu` | load, iowait, pressure, top CPU consumers |
|
|
219
|
+
| `wtf mem` | RAM/swap, OOM kills, top memory consumers |
|
|
220
|
+
| `wtf net` | interfaces, gateway, DNS, errors, listening ports |
|
|
221
|
+
| `wtf io` | per-device IO rates, pressure, stuck processes |
|
|
222
|
+
| `wtf who` | logged-in users, recent logins, failed auth |
|
|
223
|
+
| `wtf info` | one-page snapshot: all of the above at once |
|
|
224
|
+
| `wtf top` | focused process top: sort by cpu/rss, filter user/name |
|
|
225
|
+
| `wtf ports` | listening sockets with owning PID/user/command |
|
|
226
|
+
| `wtf service NAME` | drilldown one service: state, restarts, mem, ports, journal |
|
|
227
|
+
| `wtf logs` | recent ERROR+ journal entries grouped by service |
|
|
228
|
+
| `wtf events` | chronological timeline: reboots, OOM, failed units, … |
|
|
229
|
+
| `wtf history` | list saved audit snapshots (`wtf audit --save` to create) |
|
|
230
|
+
| `wtf diff` | compare current state to a saved snapshot |
|
|
231
|
+
| `wtf crontab` | validate all standard crontab locations + per-user crontabs |
|
|
232
|
+
| `wtf doctor` | self-diagnostic: which tools wtftools can actually use |
|
|
233
|
+
| `wtf config` | show effective config / print example |
|
|
234
|
+
|
|
235
|
+
`wtftools` absorbs and supersedes
|
|
236
|
+
[`checkcrontab`](https://github.com/wachawo/checkcrontab) — the same cron
|
|
237
|
+
validator now lives at `wtf crontab`.
|
|
238
|
+
|
|
239
|
+
## Advanced audit options
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
wtf audit -v # show extra detail (failed units, OOM events)
|
|
243
|
+
wtf audit --strict # exit 1 on warnings (CI-friendly)
|
|
244
|
+
wtf audit --check memory --check disks # run named checks only
|
|
245
|
+
wtf audit --list-checks # show all available check short-names
|
|
246
|
+
wtf audit --since 1 # look-back window for OOM/auth/kernel (default 24h)
|
|
247
|
+
wtf audit --ignore swap --ignore "disk /mnt/Backup" # silence checks
|
|
248
|
+
wtf audit --format csv > audit.csv # spreadsheet-friendly
|
|
249
|
+
wtf audit --format html -o report.html # self-contained HTML for tickets
|
|
250
|
+
wtf audit --format prometheus # metrics for node_exporter textfile
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Built-in checks
|
|
254
|
+
|
|
255
|
+
uptime · system state · load average · CPU iowait · PSI cpu/memory/io ·
|
|
256
|
+
TCP retransmits · memory · swap · disk (per mount) · inodes ·
|
|
257
|
+
read-only mounts · failed systemd units · enabled-but-down services ·
|
|
258
|
+
restart loops · network errors · conntrack · journal disk usage · zombies ·
|
|
259
|
+
D-state processes · OOM kills · kernel errors · kernel taint · cert expiry ·
|
|
260
|
+
open file descriptors · process count · failed auth · time sync ·
|
|
261
|
+
pending updates · reboot required · cron daemon · crontab syntax · docker ·
|
|
262
|
+
hw temperatures · disk SMART · DNS · HTTP/TCP probes · fail2ban.
|
|
263
|
+
|
|
264
|
+
## Config
|
|
265
|
+
|
|
266
|
+
Thresholds and ignores live in an INI file at any of:
|
|
267
|
+
|
|
268
|
+
- `/etc/wtftools/config.ini`
|
|
269
|
+
- `/etc/wtf/config.ini`
|
|
270
|
+
- `~/.config/wtftools/config.ini`
|
|
271
|
+
|
|
272
|
+
Run `wtf config --example` for a fully-commented template. Headlines:
|
|
273
|
+
|
|
274
|
+
```ini
|
|
275
|
+
[thresholds]
|
|
276
|
+
disk_warn = 85
|
|
277
|
+
disk_fail = 95
|
|
278
|
+
swap_warn = 50
|
|
279
|
+
swap_fail = 90
|
|
280
|
+
|
|
281
|
+
[ignore]
|
|
282
|
+
checks = swap, updates
|
|
283
|
+
result_names =
|
|
284
|
+
disk /mnt/Backup
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## Compatibility
|
|
288
|
+
|
|
289
|
+
- Python 3.8+
|
|
290
|
+
- Linux (systemd distributions are the happy path; the tool degrades
|
|
291
|
+
gracefully when `systemctl` / `journalctl` / `psutil` are missing)
|
|
292
|
+
- No network access required for the core CLI
|
|
293
|
+
- Optional network: `wtf explain --llm claude/openai`, `wtf doctor --check-updates`
|
|
294
|
+
|
|
295
|
+
## From source
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
git clone https://github.com/wachawo/wtftools
|
|
299
|
+
cd wtftools
|
|
300
|
+
pip install -e .
|
|
301
|
+
# or test without installing:
|
|
302
|
+
python3 wtf.py audit
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## License
|
|
306
|
+
|
|
307
|
+
MIT
|
wtftools-0.0.1/README.md
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# wtftools
|
|
2
|
+
|
|
3
|
+
[](https://github.com/wachawo/wtftools/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/wtftools/)
|
|
5
|
+
[](https://pypi.org/project/wtftools/)
|
|
6
|
+
[](https://github.com/wachawo/wtftools/blob/main/LICENSE)
|
|
7
|
+
[](https://pypi.org/project/wtftools/)
|
|
8
|
+
|
|
9
|
+
> One command to see what is going on with your Linux server right now.
|
|
10
|
+
|
|
11
|
+
**English** | [Español](https://github.com/wachawo/wtftools/blob/main/docs/README_ES.md) | [Português](https://github.com/wachawo/wtftools/blob/main/docs/README_PT.md) | [Français](https://github.com/wachawo/wtftools/blob/main/docs/README_FR.md) | [Deutsch](https://github.com/wachawo/wtftools/blob/main/docs/README_DE.md) | [Italiano](https://github.com/wachawo/wtftools/blob/main/docs/README_IT.md) | [Русский](https://github.com/wachawo/wtftools/blob/main/docs/README_RU.md) | [中文](https://github.com/wachawo/wtftools/blob/main/docs/README_ZH.md) | [日本語](https://github.com/wachawo/wtftools/blob/main/docs/README_JA.md) | [हिन्दी](https://github.com/wachawo/wtftools/blob/main/docs/README_HI.md) | [한국어](https://github.com/wachawo/wtftools/blob/main/docs/README_KR.md)
|
|
12
|
+
|
|
13
|
+
You log in to a server and something feels wrong. Instead of running ten
|
|
14
|
+
commands (`htop`, `df -h`, `journalctl`, `systemctl --failed`, …) you run one:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
$ wtf
|
|
18
|
+
─────────── AUDIT ────────────
|
|
19
|
+
[ OK ] uptime 3d 4h 12m
|
|
20
|
+
[ OK ] load average 0.42 0.51 0.55 / 8 CPU
|
|
21
|
+
[ OK ] memory 4.1GB / 16.0GB used (25%)
|
|
22
|
+
[WARN] disk /var 17.0GB / 20.0GB used (85%)
|
|
23
|
+
[ OK ] zombie processes 0 zombies
|
|
24
|
+
[FAIL] failed systemd units 1 failed unit(s)
|
|
25
|
+
[ OK ] crontab syntax 14 cron line(s), no errors
|
|
26
|
+
|
|
27
|
+
Summary: 12 ok · 1 warn · 1 fail · 2 skip
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Green is fine, yellow needs a look, red needs fixing. That's it.
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pipx install wtftools # recommended — works on any modern distro
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
No `pipx`? Any of these works too:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install wtftools # classic pip (core, no dependencies)
|
|
42
|
+
pip install wtftools[full] # + psutil for richer process/socket info
|
|
43
|
+
sudo dpkg -i wtftools_*.deb # Debian/Ubuntu package (see Releases)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
After install you have the `wtf` command. Try it: `wtf`.
|
|
47
|
+
|
|
48
|
+
## The commands you will actually use
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
wtf # full health check — start here
|
|
52
|
+
wtf problems # show ONLY what is wrong (warnings + failures)
|
|
53
|
+
wtf explain # what to do about each problem, step by step
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Then ask about one resource at a time, like `show` commands on a switch:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
wtf disk # is there space? per-mount usage, inodes, read-only
|
|
60
|
+
wtf disk --tree # WHAT is eating the space (largest directories)
|
|
61
|
+
wtf cpu # load, iowait, top CPU consumers
|
|
62
|
+
wtf mem # RAM/swap, OOM kills, top memory consumers
|
|
63
|
+
wtf net # interfaces, IPs, gateway, DNS, listening ports
|
|
64
|
+
wtf io # disk read/write rates, IO-stuck processes
|
|
65
|
+
wtf who # who is logged in, recent logins, failed auth
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Example — disk is filling up, find the culprit:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
$ wtf disk --tree /var
|
|
72
|
+
────────────── DISK ──────────────
|
|
73
|
+
/ [████████████████····] 79% 1.4TB / 1.8TB ext4
|
|
74
|
+
/var [█████████████████···] 85% 17.0GB / 20.0GB ext4
|
|
75
|
+
|
|
76
|
+
───────── LARGEST UNDER /var ─────────
|
|
77
|
+
15.0GB /var/lib
|
|
78
|
+
3.1GB /var/log
|
|
79
|
+
1.8GB /var/log/app
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`wtf disk --tree` without a path picks the fullest mount automatically.
|
|
83
|
+
|
|
84
|
+
Learning Linux? Add `--show-commands` to any resource command and it also
|
|
85
|
+
prints the classic commands it replaces, so you can run them yourself:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
$ wtf cpu --show-commands
|
|
89
|
+
...
|
|
90
|
+
equivalent commands:
|
|
91
|
+
$ uptime
|
|
92
|
+
$ top -bn1 | head
|
|
93
|
+
$ ps aux --sort=-%cpu | head
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## When something is broken
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
wtf problems -v # every problem, with detail
|
|
100
|
+
wtf events --since 6 # timeline: reboots, OOM kills, failed units
|
|
101
|
+
wtf service nginx # one service: state, restarts, ports, journal
|
|
102
|
+
wtf logs --since '2 hours ago' # recent ERROR+ journal entries by service
|
|
103
|
+
wtf explain # actionable advice per finding
|
|
104
|
+
wtf explain --llm ollama # or let a local LLM summarize it
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Output for scripts: grep, awk, jq
|
|
108
|
+
|
|
109
|
+
Colors disappear automatically when you pipe, so plain `grep` always works.
|
|
110
|
+
Every command also has machine-readable formats — `plain` (tab-separated,
|
|
111
|
+
no headers) and `json`. The flag works before the subcommand too:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
wtf -f json disk # same as: wtf disk --format json
|
|
115
|
+
wtf disk --format plain # tab-separated, no headers
|
|
116
|
+
wtf disk --format json | jq . # full JSON
|
|
117
|
+
|
|
118
|
+
# mounts above 80%:
|
|
119
|
+
wtf disk --format json | jq -r '.mounts[] | select(.percent > 80) | .target'
|
|
120
|
+
|
|
121
|
+
# failed checks only, names column:
|
|
122
|
+
wtf audit --format plain | awk -F'\t' '$1 == "fail" {print $2}'
|
|
123
|
+
|
|
124
|
+
# top directory eating /var, bytes and path:
|
|
125
|
+
wtf disk --tree /var --format plain | awk -F'\t' '$1 == "tree" {print $2, $3; exit}'
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
JSON payloads of the resource commands carry `schema_version` so your
|
|
129
|
+
scripts survive upgrades.
|
|
130
|
+
|
|
131
|
+
## Daily routine and monitoring
|
|
132
|
+
|
|
133
|
+
One command for the morning check — audit, what changed since the last run,
|
|
134
|
+
and the event timeline, with a one-line verdict on top:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
wtf daily # audit + diff vs yesterday + events
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
It saves a snapshot on every run, so tomorrow's `wtf daily` shows the diff.
|
|
141
|
+
A crontab line for unattended use (mails only when something is wrong):
|
|
142
|
+
|
|
143
|
+
```cron
|
|
144
|
+
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
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The building blocks are also available separately:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
wtf audit --brief # one line — perfect for MOTD / SSH banner
|
|
151
|
+
wtf audit --save # save a snapshot
|
|
152
|
+
wtf diff # what changed since the last snapshot
|
|
153
|
+
wtf history # list saved snapshots
|
|
154
|
+
|
|
155
|
+
# cron alerting without any monitoring stack:
|
|
156
|
+
wtf audit --alert 'mail -s "wtf $WTF_HOST" you@example.com'
|
|
157
|
+
wtf audit --alert-on warn --alert 'curl -X POST $SLACK_WEBHOOK -d @-'
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Exit codes are CI/cron-friendly:
|
|
161
|
+
|
|
162
|
+
| code | meaning |
|
|
163
|
+
|------|--------------------------------------------------|
|
|
164
|
+
| 0 | everything OK |
|
|
165
|
+
| 1 | warnings with `--strict`, or crontab errors |
|
|
166
|
+
| 2 | audit found a `[FAIL]` |
|
|
167
|
+
| 130 | interrupted (Ctrl-C) |
|
|
168
|
+
|
|
169
|
+
## All subcommands
|
|
170
|
+
|
|
171
|
+
| command | what it does |
|
|
172
|
+
|---------------------|-------------------------------------------------------------|
|
|
173
|
+
| `wtf` / `wtf audit` | green/yellow/red checklist: what is OK and what is not |
|
|
174
|
+
| `wtf problems` | only WARN+FAIL rows |
|
|
175
|
+
| `wtf daily` | morning check: audit + diff vs last run + events |
|
|
176
|
+
| `wtf explain` | per-check actionable advice; `--llm` to pipe to an LLM |
|
|
177
|
+
| `wtf disk` | per-mount usage; `--tree` shows largest directories |
|
|
178
|
+
| `wtf cpu` | load, iowait, pressure, top CPU consumers |
|
|
179
|
+
| `wtf mem` | RAM/swap, OOM kills, top memory consumers |
|
|
180
|
+
| `wtf net` | interfaces, gateway, DNS, errors, listening ports |
|
|
181
|
+
| `wtf io` | per-device IO rates, pressure, stuck processes |
|
|
182
|
+
| `wtf who` | logged-in users, recent logins, failed auth |
|
|
183
|
+
| `wtf info` | one-page snapshot: all of the above at once |
|
|
184
|
+
| `wtf top` | focused process top: sort by cpu/rss, filter user/name |
|
|
185
|
+
| `wtf ports` | listening sockets with owning PID/user/command |
|
|
186
|
+
| `wtf service NAME` | drilldown one service: state, restarts, mem, ports, journal |
|
|
187
|
+
| `wtf logs` | recent ERROR+ journal entries grouped by service |
|
|
188
|
+
| `wtf events` | chronological timeline: reboots, OOM, failed units, … |
|
|
189
|
+
| `wtf history` | list saved audit snapshots (`wtf audit --save` to create) |
|
|
190
|
+
| `wtf diff` | compare current state to a saved snapshot |
|
|
191
|
+
| `wtf crontab` | validate all standard crontab locations + per-user crontabs |
|
|
192
|
+
| `wtf doctor` | self-diagnostic: which tools wtftools can actually use |
|
|
193
|
+
| `wtf config` | show effective config / print example |
|
|
194
|
+
|
|
195
|
+
`wtftools` absorbs and supersedes
|
|
196
|
+
[`checkcrontab`](https://github.com/wachawo/checkcrontab) — the same cron
|
|
197
|
+
validator now lives at `wtf crontab`.
|
|
198
|
+
|
|
199
|
+
## Advanced audit options
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
wtf audit -v # show extra detail (failed units, OOM events)
|
|
203
|
+
wtf audit --strict # exit 1 on warnings (CI-friendly)
|
|
204
|
+
wtf audit --check memory --check disks # run named checks only
|
|
205
|
+
wtf audit --list-checks # show all available check short-names
|
|
206
|
+
wtf audit --since 1 # look-back window for OOM/auth/kernel (default 24h)
|
|
207
|
+
wtf audit --ignore swap --ignore "disk /mnt/Backup" # silence checks
|
|
208
|
+
wtf audit --format csv > audit.csv # spreadsheet-friendly
|
|
209
|
+
wtf audit --format html -o report.html # self-contained HTML for tickets
|
|
210
|
+
wtf audit --format prometheus # metrics for node_exporter textfile
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Built-in checks
|
|
214
|
+
|
|
215
|
+
uptime · system state · load average · CPU iowait · PSI cpu/memory/io ·
|
|
216
|
+
TCP retransmits · memory · swap · disk (per mount) · inodes ·
|
|
217
|
+
read-only mounts · failed systemd units · enabled-but-down services ·
|
|
218
|
+
restart loops · network errors · conntrack · journal disk usage · zombies ·
|
|
219
|
+
D-state processes · OOM kills · kernel errors · kernel taint · cert expiry ·
|
|
220
|
+
open file descriptors · process count · failed auth · time sync ·
|
|
221
|
+
pending updates · reboot required · cron daemon · crontab syntax · docker ·
|
|
222
|
+
hw temperatures · disk SMART · DNS · HTTP/TCP probes · fail2ban.
|
|
223
|
+
|
|
224
|
+
## Config
|
|
225
|
+
|
|
226
|
+
Thresholds and ignores live in an INI file at any of:
|
|
227
|
+
|
|
228
|
+
- `/etc/wtftools/config.ini`
|
|
229
|
+
- `/etc/wtf/config.ini`
|
|
230
|
+
- `~/.config/wtftools/config.ini`
|
|
231
|
+
|
|
232
|
+
Run `wtf config --example` for a fully-commented template. Headlines:
|
|
233
|
+
|
|
234
|
+
```ini
|
|
235
|
+
[thresholds]
|
|
236
|
+
disk_warn = 85
|
|
237
|
+
disk_fail = 95
|
|
238
|
+
swap_warn = 50
|
|
239
|
+
swap_fail = 90
|
|
240
|
+
|
|
241
|
+
[ignore]
|
|
242
|
+
checks = swap, updates
|
|
243
|
+
result_names =
|
|
244
|
+
disk /mnt/Backup
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Compatibility
|
|
248
|
+
|
|
249
|
+
- Python 3.8+
|
|
250
|
+
- Linux (systemd distributions are the happy path; the tool degrades
|
|
251
|
+
gracefully when `systemctl` / `journalctl` / `psutil` are missing)
|
|
252
|
+
- No network access required for the core CLI
|
|
253
|
+
- Optional network: `wtf explain --llm claude/openai`, `wtf doctor --check-updates`
|
|
254
|
+
|
|
255
|
+
## From source
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
git clone https://github.com/wachawo/wtftools
|
|
259
|
+
cd wtftools
|
|
260
|
+
pip install -e .
|
|
261
|
+
# or test without installing:
|
|
262
|
+
python3 wtf.py audit
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## License
|
|
266
|
+
|
|
267
|
+
MIT
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["setuptools>=
|
|
2
|
+
requires = ["setuptools>=77", "wheel"]
|
|
3
3
|
build-backend = "setuptools.build_meta"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "wtftools"
|
|
7
|
-
version = "0.0.
|
|
7
|
+
version = "0.0.1"
|
|
8
8
|
description = "One command to see what is going on with your Linux server right now."
|
|
9
9
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
10
|
-
license =
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
11
12
|
requires-python = ">=3.8"
|
|
12
13
|
authors = [{ name = "Aleksandr Pimenov", email = "wachawo@gmail.com" }]
|
|
13
14
|
maintainers = [{ name = "Aleksandr Pimenov", email = "wachawo@gmail.com" }]
|
|
@@ -16,7 +17,6 @@ classifiers = [
|
|
|
16
17
|
"Development Status :: 4 - Beta",
|
|
17
18
|
"Intended Audience :: System Administrators",
|
|
18
19
|
"Intended Audience :: Developers",
|
|
19
|
-
"License :: OSI Approved :: MIT License",
|
|
20
20
|
"Programming Language :: Python :: 3",
|
|
21
21
|
"Programming Language :: Python :: 3.8",
|
|
22
22
|
"Programming Language :: Python :: 3.9",
|