wtftools 0.0.0__tar.gz → 0.0.2__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.
Files changed (58) hide show
  1. {wtftools-0.0.0 → wtftools-0.0.2}/CHANGELOG.md +138 -2
  2. {wtftools-0.0.0 → wtftools-0.0.2}/MANIFEST.in +2 -1
  3. wtftools-0.0.2/PKG-INFO +184 -0
  4. wtftools-0.0.2/README.md +145 -0
  5. wtftools-0.0.0/scripts/wtf.bash-completion → wtftools-0.0.2/completions/wtf +49 -10
  6. {wtftools-0.0.0 → wtftools-0.0.2}/pyproject.toml +11 -7
  7. wtftools-0.0.2/scripts/build-deb.sh +63 -0
  8. {wtftools-0.0.0 → wtftools-0.0.2}/tests/test_audit.py +4 -1
  9. {wtftools-0.0.0 → wtftools-0.0.2}/tests/test_audit_extras.py +3 -0
  10. {wtftools-0.0.0 → wtftools-0.0.2}/tests/test_colors.py +11 -12
  11. wtftools-0.0.2/tests/test_completion.py +56 -0
  12. wtftools-0.0.0/tests/test_iteration5.py → wtftools-0.0.2/tests/test_conntrack_alert_explain.py +1 -5
  13. wtftools-0.0.2/tests/test_disk_usage.py +194 -0
  14. {wtftools-0.0.0 → wtftools-0.0.2}/tests/test_explain_deep.py +2 -2
  15. wtftools-0.0.0/tests/test_iteration10.py → wtftools-0.0.2/tests/test_llm_html_output.py +29 -5
  16. {wtftools-0.0.0 → wtftools-0.0.2}/tests/test_main.py +80 -2
  17. {wtftools-0.0.0 → wtftools-0.0.2}/tests/test_main_extras.py +0 -3
  18. wtftools-0.0.0/tests/test_iteration2_extras.py → wtftools-0.0.2/tests/test_net_restart_checks.py +1 -6
  19. wtftools-0.0.2/tests/test_plain_formats.py +203 -0
  20. wtftools-0.0.2/tests/test_port_docker.py +542 -0
  21. wtftools-0.0.0/tests/test_iteration8.py → wtftools-0.0.2/tests/test_probes_smart_diff.py +1 -1
  22. wtftools-0.0.0/tests/test_iteration4.py → wtftools-0.0.2/tests/test_psi_cert_logs_parallel.py +1 -1
  23. {wtftools-0.0.0 → wtftools-0.0.2}/tests/test_public_api.py +15 -12
  24. wtftools-0.0.0/tests/test_iteration6.py → wtftools-0.0.2/tests/test_snapshot_docker_ntp.py +12 -7
  25. {wtftools-0.0.0 → wtftools-0.0.2}/tests/test_sysinfo.py +1 -0
  26. wtftools-0.0.0/tests/test_iteration3.py → wtftools-0.0.2/tests/test_tcp_services_config.py +1 -1
  27. wtftools-0.0.2/tests/test_temp.py +66 -0
  28. wtftools-0.0.0/tests/test_iteration7.py → wtftools-0.0.2/tests/test_temp_dns_top_ports.py +23 -28
  29. {wtftools-0.0.0 → wtftools-0.0.2}/wtftools/colors.py +6 -16
  30. wtftools-0.0.2/wtftools/completion.py +217 -0
  31. {wtftools-0.0.0 → wtftools-0.0.2}/wtftools/info.py +36 -6
  32. {wtftools-0.0.0 → wtftools-0.0.2}/wtftools/llm.py +15 -10
  33. {wtftools-0.0.0 → wtftools-0.0.2}/wtftools/main.py +601 -75
  34. wtftools-0.0.2/wtftools/sections.py +443 -0
  35. {wtftools-0.0.0 → wtftools-0.0.2}/wtftools/snapshot.py +6 -2
  36. {wtftools-0.0.0 → wtftools-0.0.2}/wtftools/sysinfo.py +353 -1
  37. wtftools-0.0.2/wtftools.egg-info/PKG-INFO +184 -0
  38. {wtftools-0.0.0 → wtftools-0.0.2}/wtftools.egg-info/SOURCES.txt +16 -9
  39. wtftools-0.0.0/PKG-INFO +0 -246
  40. wtftools-0.0.0/README.md +0 -184
  41. wtftools-0.0.0/scripts/build-deb.sh +0 -33
  42. wtftools-0.0.0/wtftools.egg-info/PKG-INFO +0 -246
  43. {wtftools-0.0.0 → wtftools-0.0.2}/LICENSE +0 -0
  44. {wtftools-0.0.0 → wtftools-0.0.2}/setup.cfg +0 -0
  45. {wtftools-0.0.0 → wtftools-0.0.2}/tests/test_config.py +0 -0
  46. {wtftools-0.0.0 → wtftools-0.0.2}/tests/test_cron.py +0 -0
  47. {wtftools-0.0.0 → wtftools-0.0.2}/tests/test_info.py +0 -0
  48. {wtftools-0.0.0 → wtftools-0.0.2}/wtftools/__init__.py +0 -0
  49. {wtftools-0.0.0 → wtftools-0.0.2}/wtftools/__main__.py +0 -0
  50. {wtftools-0.0.0 → wtftools-0.0.2}/wtftools/audit.py +0 -0
  51. {wtftools-0.0.0 → wtftools-0.0.2}/wtftools/config.py +0 -0
  52. {wtftools-0.0.0 → wtftools-0.0.2}/wtftools/cron.py +0 -0
  53. {wtftools-0.0.0 → wtftools-0.0.2}/wtftools/events.py +0 -0
  54. {wtftools-0.0.0 → wtftools-0.0.2}/wtftools/explain.py +0 -0
  55. {wtftools-0.0.0 → wtftools-0.0.2}/wtftools.egg-info/dependency_links.txt +0 -0
  56. {wtftools-0.0.0 → wtftools-0.0.2}/wtftools.egg-info/entry_points.txt +0 -0
  57. {wtftools-0.0.0 → wtftools-0.0.2}/wtftools.egg-info/requires.txt +0 -0
  58. {wtftools-0.0.0 → wtftools-0.0.2}/wtftools.egg-info/top_level.txt +0 -0
@@ -6,12 +6,148 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.0.2] - 2026-07-01
10
+
11
+ ### Docs
12
+ - README is now a concise landing page (what it is, capabilities, install, a
13
+ linked command reference). The detailed per-command examples moved into
14
+ `docs/AUDIT.md`, `docs/RESOURCES.md`, `docs/OUTPUT.md` and `docs/CONFIG.md`,
15
+ linked from the command tables. Translations mirror the landing README;
16
+ the deep reference pages are English.
17
+
18
+ ### Added
19
+ - `wtf completion [bash|zsh]` — print a shell-completion script to enable
20
+ `<Tab>` completion (`eval "$(wtf completion bash)"`); bare `wtf completion`
21
+ prints setup instructions. The bash script lives in `wtftools/completion.py`
22
+ as the single source of truth; `completions/wtf` is a generated mirror
23
+ (a test guards against drift), installed to bash-completion's system dir.
24
+
25
+ ### Changed — `wtf disk` folder usage
26
+ - `wtf disk <path>` now breaks a directory down by folder size, biggest first
27
+ (like `du -sh <path>/* | sort`), as `# DISK USAGE <path>` rows of
28
+ `path/ size % of analysed root depth` (the depth index is the last
29
+ column). `wtf disk` with no path still shows the per-mount overview, now laid
30
+ out as `full path used/total percent bar` (full mount paths, no
31
+ truncation).
32
+ - `--tree [N]` drills into the N largest folders at each level (bare `--tree` =
33
+ 1 → a single dominant chain); `--depth D` sets how deep (default 3). Output
34
+ is parse-first: `plain` is `bytes<TAB>percent<TAB>abspath<TAB>depth`, `json`
35
+ is a flat `entries` list with absolute `path` + relative `rel`.
36
+ - **Breaking:** `--tree` used to take a PATH (`wtf disk --tree /var`); the path
37
+ is now the positional argument (`wtf disk /var --tree`) and `--tree` is the
38
+ expansion count. The `du` scan timeout was raised (30→120s) so large
39
+ filesystems no longer return an empty result.
40
+
41
+ ### Fixed
42
+ - `wtf ports` and `wtf top` JSON is now an object carrying `schema_version`
43
+ (was a bare array), consistent with `disk`/`net`; `wtf audit` JSON carries
44
+ `schema_version` too.
45
+ - README documentation links are absolute so they resolve on the PyPI project
46
+ page; the translated READMEs no longer link to a non-existent `docs/docs/`
47
+ path.
48
+ - `.deb` install instructions use the actual package name
49
+ (`python3-wtftools_*.deb`).
50
+ - Unexpected errors now print a one-line message instead of dumping a raw
51
+ Python traceback; set `WTFTOOLS_DEBUG=1` or pass `--verbose` for the trace.
52
+ - `requirements.txt` no longer pulls `psutil` — the core install stays
53
+ dependency-free; use `pip install "wtftools[full]"` for psutil.
54
+ - The packaged bash-completion installs as `completions/wtf`, so it is
55
+ auto-loaded system-wide (the previous file name prevented auto-loading; the
56
+ `eval "$(wtf completion bash)"` path was unaffected).
57
+ - The Docker base image is pinned by digest for reproducible builds.
58
+ - Minimum Python raised to 3.9 (`requires-python`): the build needs
59
+ setuptools>=77, which dropped the EOL Python 3.8. The source stays
60
+ 3.8-compatible in style; only the packaged build floor moved.
61
+
62
+ ### Security
63
+ - `wtf explain --llm claude|openai` discloses (to stderr) that the host name
64
+ and audit findings are sent to the vendor, and asks for confirmation on an
65
+ interactive terminal (`--yes` / `WTFTOOLS_LLM_YES=1` to skip). `--llm auto`
66
+ no longer silently escalates to a remote model — it uses local `ollama` only.
67
+ - `wtf audit --format csv` escapes cells beginning with `= + - @` to prevent
68
+ spreadsheet formula injection.
69
+ - Snapshot files and their directory are created `0600`/`0700`, so root's audit
70
+ history is not world-readable on a multi-user host.
71
+ - `wtf crontab -u <user>` validates the username (same rule as positional
72
+ targets) before shelling out to `crontab -l -u`, avoiding argument injection.
73
+
74
+ ## [0.0.1] - 2026-06-14
75
+
76
+ ### Added — port, docker and temperature views
77
+ - `wtf port <N>` (alias of `wtf ports <N>`) — drill into a single port:
78
+ which process holds it (PID, user, command), the exact executable file
79
+ behind it and its working directory, via `lsof` with `/proc` enrichment
80
+ and psutil/`ss` fallbacks. text/plain/json output.
81
+ - `wtf docker [NAME]` — where a container was started from: the compose
82
+ project working directory and config files read from the container's
83
+ labels, plus on-disk sizes (image layers, writable container layer and
84
+ json log). With no name it lists running containers as a table with
85
+ image/container/log size columns and a TOTAL row. Sizes use decimal units
86
+ (1GB = 1000MB) to match `docker container ls --size`. The image total
87
+ dedupes by image id (one image shared by many containers counted once); it is
88
+ the logical unique-images size, and since different images still share base
89
+ layers on disk, the real layer-deduplicated disk is shown alongside it from
90
+ `docker system df`. Container (writable layer) and log totals are exact. Log
91
+ sizes need read access under `/var/lib/docker` (run with `sudo`); otherwise
92
+ the column and its total show `?`, not a misleading `0B`.
93
+ - `wtf temp` (aliases `temps`, `temperature`) — hardware temperatures from
94
+ `/sys/class/hwmon` sensors, sorted hottest-first and colored against the
95
+ configured warn/fail thresholds. text/plain/json output.
96
+
97
+ ### Changed — output
98
+ - Section headers are now plain `# TITLE` lines instead of full-width
99
+ centered box-drawing rules, so the output greps cleanly (`grep '^#'`).
100
+
101
+ ### CI
102
+ - Bumped GitHub Actions to the Node.js 24 majors (checkout v6,
103
+ setup-python v6, action-gh-release v3).
104
+
105
+ ### Added — per-resource subcommands
106
+ - `wtf disk` — per-mount usage with inode percent and read-only flags;
107
+ `--tree [PATH]` lists the largest directories (du-based, `--depth`,
108
+ `--top`); without PATH it picks the fullest mount automatically.
109
+ - `wtf cpu` — model, loadavg (+per-cpu), iowait, PSI, top-5 by CPU.
110
+ - `wtf mem` — RAM/swap, PSI, OOM kills in the look-back window, top-5 by RSS.
111
+ - `wtf net` — interfaces, default gateway, DNS servers, interface error
112
+ counters, listening TCP ports summary.
113
+ - `wtf io` — PSI io, iowait, per-device read/write rates and utilization
114
+ (sampled from `/proc/diskstats`), D-state processes.
115
+ - `wtf who` — logged-in users, recent logins, failed-auth count.
116
+ - All six support `--format text|plain|json`; `plain` is tab-separated for
117
+ awk/grep, JSON includes `schema_version`.
118
+ - New module `wtftools/sections.py`; new sysinfo helpers:
119
+ `get_default_gateway`, `get_dns_servers`, `get_logged_in_users`,
120
+ `get_du_tree`, `get_disk_io_per_device`.
121
+
122
+ ### Added — teaching mode
123
+ - `--show-commands` on `disk`/`cpu`/`mem`/`net`/`io`/`who` prints the
124
+ classic commands each view replaces (`df -h`, `ss -tlnp`, …), so the
125
+ output can be learned from and double-checked by hand.
126
+
127
+ ### Added — daily routine and pipeline output
128
+ - `wtf daily` — the morning check as one command: one-line verdict, diff
129
+ vs the previous snapshot, event timeline and the full audit; saves a
130
+ snapshot on every run so the next day diffs against it.
131
+ - `--format plain` for `top`, `ports`, `events`, `logs`, `services` and
132
+ `info` — every command now has a tab-separated twin for grep/awk.
133
+ - Global `-f/--format` flag: `wtf -f json disk` works; a `--format` given
134
+ after the subcommand still wins.
135
+ - `schema_version` added to the JSON payloads of `info`, `events`, `logs`,
136
+ `services` and `daily`.
137
+
138
+ ### Changed
139
+ - `wtf ports` no longer fails without psutil — it falls back to an
140
+ `ss`-based TCP listing (no PID/user info; UDP still needs psutil).
141
+ - `wtf service` is now an alias for `wtf services`.
142
+ - README restructured for first-time users: install + the most-used
143
+ commands up top, scripting (grep/awk/jq) cookbook, advanced flags below.
144
+ - Bash completion covers the new subcommands.
145
+
9
146
  ### Removed — plugin infrastructure
10
147
  - `wtftools/plugin_sdk.py` — Python helper for plugin authors.
11
148
  - `wtftools/checks/plugins.py` — discovery / executor / parser for
12
149
  `/etc/wtf/checks.d/` scripts (bash + Python).
13
150
  - `_plugin_to_check` + `_all_check_callables` glue in `wtftools/audit.py`.
14
- - `tests/test_plugins.py`, `tests/test_iteration16.py`.
15
151
  - README's «Plugins» section and QUICKSTART's «Custom checks (plugins)»
16
152
  section.
17
153
 
@@ -84,7 +220,7 @@ Initial public release. Highlights:
84
220
  release workflow.
85
221
  - **724 tests, 92.6 % coverage.**
86
222
 
87
- ### Added — Plugin SDK & docs (final iteration)
223
+ ### Added — Plugin SDK & docs
88
224
  - **`wtftools.plugin_sdk`** — tiny helper module so Python plugins don't have
89
225
  to remember exit codes or hand-roll JSON:
90
226
 
@@ -2,4 +2,5 @@ include README.md
2
2
  include LICENSE
3
3
  include CHANGELOG.md
4
4
  recursive-include wtftools *.py
5
- recursive-include scripts *.sh *.bash-completion
5
+ recursive-include scripts *.sh
6
+ include completions/wtf
@@ -0,0 +1,184 @@
1
+ Metadata-Version: 2.4
2
+ Name: wtftools
3
+ Version: 0.0.2
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.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Operating System :: POSIX :: Linux
22
+ Classifier: Topic :: System :: Systems Administration
23
+ Classifier: Topic :: System :: Monitoring
24
+ Classifier: Topic :: Utilities
25
+ Requires-Python: >=3.9
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Provides-Extra: full
29
+ Requires-Dist: psutil>=5.9.0; extra == "full"
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
32
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
33
+ Requires-Dist: coverage>=7.0.0; extra == "dev"
34
+ Requires-Dist: ruff>=0.4.0; extra == "dev"
35
+ Requires-Dist: build>=1.0.0; extra == "dev"
36
+ Requires-Dist: stdeb>=0.10.0; extra == "dev"
37
+ Requires-Dist: pre-commit>=3.0.0; extra == "dev"
38
+ Dynamic: license-file
39
+
40
+ # wtftools
41
+
42
+ [![CI](https://github.com/wachawo/wtftools/actions/workflows/ci.yml/badge.svg)](https://github.com/wachawo/wtftools/actions/workflows/ci.yml)
43
+ [![PyPI](https://img.shields.io/pypi/v/wtftools.svg)](https://pypi.org/project/wtftools/)
44
+ [![Downloads](https://img.shields.io/pypi/dm/wtftools.svg)](https://pypi.org/project/wtftools/)
45
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/wachawo/wtftools/blob/main/LICENSE)
46
+ [![Python](https://img.shields.io/pypi/pyversions/wtftools.svg)](https://pypi.org/project/wtftools/)
47
+
48
+ > One command to see what is going on with your Linux server right now.
49
+
50
+ **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)
51
+
52
+ You log in to a server and something feels wrong. Instead of running ten
53
+ commands (`htop`, `df -h`, `journalctl`, `systemctl --failed`, …) you run one:
54
+
55
+ ```
56
+ $ wtf
57
+ # AUDIT
58
+ [ OK ] uptime 3d 4h 12m
59
+ [ OK ] load average 0.42 0.51 0.55 / 8 CPU
60
+ [ OK ] memory 4.1GB / 16.0GB used (25%)
61
+ [WARN] disk /var 17.0GB / 20.0GB used (85%)
62
+ [FAIL] failed systemd units 1 failed unit(s)
63
+
64
+ Summary: 12 ok · 1 warn · 1 fail · 2 skip
65
+ ```
66
+
67
+ Green is fine, yellow needs a look, red needs fixing. `wtftools` is a
68
+ **read-only, dependency-free CLI** (Python standard library only; `psutil`
69
+ optional) that turns a pile of diagnostic commands into one readable answer —
70
+ and a machine-readable one when you pipe it.
71
+
72
+ ## What it can do
73
+
74
+ - **Health audit** — 35+ checks (disk, memory, swap, load, PSI, OOM kills,
75
+ failed units, cert expiry, SMART, temperatures, DNS, …) as a
76
+ green / yellow / red checklist.
77
+ - **Per-resource views** — ask about one thing at a time, like `show` commands
78
+ on a switch: `wtf disk`, `wtf cpu`, `wtf mem`, `wtf net`, `wtf docker`, …
79
+ - **Incident triage** — `wtf problems`, `wtf events`, `wtf logs`,
80
+ `wtf services <unit>`, `wtf explain` (optionally through a local or hosted LLM).
81
+ - **Trends & alerting** — `wtf daily`, snapshots + `wtf diff`, cron alerts —
82
+ no monitoring stack required.
83
+ - **Scriptable** — `-f json` on every command and `-f plain` (tab-separated) on
84
+ the resource and audit views; the JSON carries a `schema_version` so scripts
85
+ survive upgrades — for grep / awk / jq.
86
+ - **Beginner-friendly** — `--show-commands` prints the classic commands each
87
+ view replaces, so you can learn them by hand.
88
+
89
+ ## Install
90
+
91
+ ```bash
92
+ pipx install wtftools # recommended — works on any modern distro
93
+ pip install wtftools # or classic pip (core, no dependencies)
94
+ pip install wtftools[full] # + psutil for richer process/socket info
95
+ sudo dpkg -i python3-wtftools_*.deb # Debian/Ubuntu package (see Releases)
96
+ ```
97
+
98
+ After install you have the `wtf` command. Enable `<Tab>` completion by adding
99
+ one line to your shell rc:
100
+
101
+ ```bash
102
+ echo 'eval "$(wtf completion bash)"' >> ~/.bashrc # bash
103
+ echo 'eval "$(wtf completion zsh)"' >> ~/.zshrc # zsh
104
+ ```
105
+
106
+ New here? Start with the [5-minute quickstart](https://github.com/wachawo/wtftools/blob/main/docs/QUICKSTART.md).
107
+
108
+ ## Commands
109
+
110
+ Run `wtf <command> --help` for flags. Each command links to its reference page
111
+ with examples.
112
+
113
+ ### Health & monitoring — [docs/AUDIT.md](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md)
114
+
115
+ | command | what it does |
116
+ |---------|--------------|
117
+ | [`wtf` / `wtf audit`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-audit) | green/yellow/red checklist of what is OK and what is not |
118
+ | [`wtf problems`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-problems) | only the WARN+FAIL rows |
119
+ | [`wtf daily`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-daily) | morning check: audit + diff vs last run + events |
120
+ | [`wtf explain`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-explain) | actionable advice per finding; `--llm` to pipe to an LLM |
121
+ | [`wtf events`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-events) | timeline: reboots, OOM kills, failed units, … |
122
+ | [`wtf logs`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-logs) | recent ERROR+ journal entries grouped by service |
123
+ | [`wtf services`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-services) | drill into one unit: state, restarts, ports, journal |
124
+ | [`wtf diff`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-diff) | compare current state to a saved snapshot |
125
+ | [`wtf history`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-history) | list saved audit snapshots |
126
+ | [`wtf crontab`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-crontab) | validate system + per-user crontabs |
127
+ | [`wtf doctor`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-doctor) | self-diagnostic: which tools/files wtf can use |
128
+
129
+ ### Resource views — [docs/RESOURCES.md](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md)
130
+
131
+ | command | what it does |
132
+ |---------|--------------|
133
+ | [`wtf disk [PATH]`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-disk) | mounts overview; with a PATH, the largest folders; `--tree` drills in |
134
+ | [`wtf cpu`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-cpu) | load, iowait, pressure, top CPU consumers |
135
+ | [`wtf mem`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-mem) | RAM/swap, OOM kills, top memory consumers |
136
+ | [`wtf net`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-net) | interfaces, gateway, DNS, errors, listening ports |
137
+ | [`wtf io`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-io) | per-device IO rates, pressure, stuck processes |
138
+ | [`wtf who`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-who) | logged-in users, recent logins, failed auth |
139
+ | [`wtf temp`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-temp) | hardware temperatures from /sys/class/hwmon |
140
+ | [`wtf info`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-info) | one-page snapshot: all of the above at once |
141
+ | [`wtf top`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-top) | focused process top: sort by cpu/rss, filter by user/name |
142
+ | [`wtf ports` / `wtf port N`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-ports) | listening sockets; drill one port to PID, exe, cwd |
143
+ | [`wtf docker [NAME]`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-docker) | container compose dir + image/container/log sizes |
144
+
145
+ ### Output & configuration
146
+
147
+ | command | what it does |
148
+ |---------|--------------|
149
+ | [`wtf config`](https://github.com/wachawo/wtftools/blob/main/docs/CONFIG.md#wtf-config) | show effective config / print a commented example |
150
+ | [`wtf completion`](#install) | print a bash/zsh `<Tab>`-completion script |
151
+ | [machine output](https://github.com/wachawo/wtftools/blob/main/docs/OUTPUT.md) | `plain`/`json` formats and a grep·awk·jq cookbook |
152
+
153
+ `wtftools` absorbs and supersedes
154
+ [`checkcrontab`](https://github.com/wachawo/checkcrontab) — the same cron
155
+ validator now lives at `wtf crontab`.
156
+
157
+ ## Documentation
158
+
159
+ - [QUICKSTART.md](https://github.com/wachawo/wtftools/blob/main/docs/QUICKSTART.md) — 5-minute onboarding and a cheat sheet
160
+ - [AUDIT.md](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md) — health checks, monitoring, exit codes, the full check list
161
+ - [RESOURCES.md](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md) — per-resource views with examples
162
+ - [OUTPUT.md](https://github.com/wachawo/wtftools/blob/main/docs/OUTPUT.md) — `plain`/`json` formats and the scripting cookbook
163
+ - [CONFIG.md](https://github.com/wachawo/wtftools/blob/main/docs/CONFIG.md) — config file, thresholds, ignoring checks
164
+
165
+ ## Compatibility
166
+
167
+ - Python 3.9+
168
+ - Linux (systemd distributions are the happy path; the tool degrades
169
+ gracefully when `systemctl` / `journalctl` / `psutil` are missing)
170
+ - No network access required for the core CLI; optional network only for
171
+ `wtf explain --llm …` and `wtf doctor --check-updates`
172
+
173
+ ## From source
174
+
175
+ ```bash
176
+ git clone https://github.com/wachawo/wtftools
177
+ cd wtftools
178
+ pip install -e .
179
+ python3 wtf.py audit # or run it without installing
180
+ ```
181
+
182
+ ## License
183
+
184
+ MIT
@@ -0,0 +1,145 @@
1
+ # wtftools
2
+
3
+ [![CI](https://github.com/wachawo/wtftools/actions/workflows/ci.yml/badge.svg)](https://github.com/wachawo/wtftools/actions/workflows/ci.yml)
4
+ [![PyPI](https://img.shields.io/pypi/v/wtftools.svg)](https://pypi.org/project/wtftools/)
5
+ [![Downloads](https://img.shields.io/pypi/dm/wtftools.svg)](https://pypi.org/project/wtftools/)
6
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/wachawo/wtftools/blob/main/LICENSE)
7
+ [![Python](https://img.shields.io/pypi/pyversions/wtftools.svg)](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
+ [FAIL] failed systemd units 1 failed unit(s)
24
+
25
+ Summary: 12 ok · 1 warn · 1 fail · 2 skip
26
+ ```
27
+
28
+ Green is fine, yellow needs a look, red needs fixing. `wtftools` is a
29
+ **read-only, dependency-free CLI** (Python standard library only; `psutil`
30
+ optional) that turns a pile of diagnostic commands into one readable answer —
31
+ and a machine-readable one when you pipe it.
32
+
33
+ ## What it can do
34
+
35
+ - **Health audit** — 35+ checks (disk, memory, swap, load, PSI, OOM kills,
36
+ failed units, cert expiry, SMART, temperatures, DNS, …) as a
37
+ green / yellow / red checklist.
38
+ - **Per-resource views** — ask about one thing at a time, like `show` commands
39
+ on a switch: `wtf disk`, `wtf cpu`, `wtf mem`, `wtf net`, `wtf docker`, …
40
+ - **Incident triage** — `wtf problems`, `wtf events`, `wtf logs`,
41
+ `wtf services <unit>`, `wtf explain` (optionally through a local or hosted LLM).
42
+ - **Trends & alerting** — `wtf daily`, snapshots + `wtf diff`, cron alerts —
43
+ no monitoring stack required.
44
+ - **Scriptable** — `-f json` on every command and `-f plain` (tab-separated) on
45
+ the resource and audit views; the JSON carries a `schema_version` so scripts
46
+ survive upgrades — for grep / awk / jq.
47
+ - **Beginner-friendly** — `--show-commands` prints the classic commands each
48
+ view replaces, so you can learn them by hand.
49
+
50
+ ## Install
51
+
52
+ ```bash
53
+ pipx install wtftools # recommended — works on any modern distro
54
+ pip install wtftools # or classic pip (core, no dependencies)
55
+ pip install wtftools[full] # + psutil for richer process/socket info
56
+ sudo dpkg -i python3-wtftools_*.deb # Debian/Ubuntu package (see Releases)
57
+ ```
58
+
59
+ After install you have the `wtf` command. Enable `<Tab>` completion by adding
60
+ one line to your shell rc:
61
+
62
+ ```bash
63
+ echo 'eval "$(wtf completion bash)"' >> ~/.bashrc # bash
64
+ echo 'eval "$(wtf completion zsh)"' >> ~/.zshrc # zsh
65
+ ```
66
+
67
+ New here? Start with the [5-minute quickstart](https://github.com/wachawo/wtftools/blob/main/docs/QUICKSTART.md).
68
+
69
+ ## Commands
70
+
71
+ Run `wtf <command> --help` for flags. Each command links to its reference page
72
+ with examples.
73
+
74
+ ### Health & monitoring — [docs/AUDIT.md](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md)
75
+
76
+ | command | what it does |
77
+ |---------|--------------|
78
+ | [`wtf` / `wtf audit`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-audit) | green/yellow/red checklist of what is OK and what is not |
79
+ | [`wtf problems`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-problems) | only the WARN+FAIL rows |
80
+ | [`wtf daily`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-daily) | morning check: audit + diff vs last run + events |
81
+ | [`wtf explain`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-explain) | actionable advice per finding; `--llm` to pipe to an LLM |
82
+ | [`wtf events`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-events) | timeline: reboots, OOM kills, failed units, … |
83
+ | [`wtf logs`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-logs) | recent ERROR+ journal entries grouped by service |
84
+ | [`wtf services`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-services) | drill into one unit: state, restarts, ports, journal |
85
+ | [`wtf diff`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-diff) | compare current state to a saved snapshot |
86
+ | [`wtf history`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-history) | list saved audit snapshots |
87
+ | [`wtf crontab`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-crontab) | validate system + per-user crontabs |
88
+ | [`wtf doctor`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-doctor) | self-diagnostic: which tools/files wtf can use |
89
+
90
+ ### Resource views — [docs/RESOURCES.md](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md)
91
+
92
+ | command | what it does |
93
+ |---------|--------------|
94
+ | [`wtf disk [PATH]`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-disk) | mounts overview; with a PATH, the largest folders; `--tree` drills in |
95
+ | [`wtf cpu`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-cpu) | load, iowait, pressure, top CPU consumers |
96
+ | [`wtf mem`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-mem) | RAM/swap, OOM kills, top memory consumers |
97
+ | [`wtf net`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-net) | interfaces, gateway, DNS, errors, listening ports |
98
+ | [`wtf io`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-io) | per-device IO rates, pressure, stuck processes |
99
+ | [`wtf who`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-who) | logged-in users, recent logins, failed auth |
100
+ | [`wtf temp`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-temp) | hardware temperatures from /sys/class/hwmon |
101
+ | [`wtf info`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-info) | one-page snapshot: all of the above at once |
102
+ | [`wtf top`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-top) | focused process top: sort by cpu/rss, filter by user/name |
103
+ | [`wtf ports` / `wtf port N`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-ports) | listening sockets; drill one port to PID, exe, cwd |
104
+ | [`wtf docker [NAME]`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-docker) | container compose dir + image/container/log sizes |
105
+
106
+ ### Output & configuration
107
+
108
+ | command | what it does |
109
+ |---------|--------------|
110
+ | [`wtf config`](https://github.com/wachawo/wtftools/blob/main/docs/CONFIG.md#wtf-config) | show effective config / print a commented example |
111
+ | [`wtf completion`](#install) | print a bash/zsh `<Tab>`-completion script |
112
+ | [machine output](https://github.com/wachawo/wtftools/blob/main/docs/OUTPUT.md) | `plain`/`json` formats and a grep·awk·jq cookbook |
113
+
114
+ `wtftools` absorbs and supersedes
115
+ [`checkcrontab`](https://github.com/wachawo/checkcrontab) — the same cron
116
+ validator now lives at `wtf crontab`.
117
+
118
+ ## Documentation
119
+
120
+ - [QUICKSTART.md](https://github.com/wachawo/wtftools/blob/main/docs/QUICKSTART.md) — 5-minute onboarding and a cheat sheet
121
+ - [AUDIT.md](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md) — health checks, monitoring, exit codes, the full check list
122
+ - [RESOURCES.md](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md) — per-resource views with examples
123
+ - [OUTPUT.md](https://github.com/wachawo/wtftools/blob/main/docs/OUTPUT.md) — `plain`/`json` formats and the scripting cookbook
124
+ - [CONFIG.md](https://github.com/wachawo/wtftools/blob/main/docs/CONFIG.md) — config file, thresholds, ignoring checks
125
+
126
+ ## Compatibility
127
+
128
+ - Python 3.9+
129
+ - Linux (systemd distributions are the happy path; the tool degrades
130
+ gracefully when `systemctl` / `journalctl` / `psutil` are missing)
131
+ - No network access required for the core CLI; optional network only for
132
+ `wtf explain --llm …` and `wtf doctor --check-updates`
133
+
134
+ ## From source
135
+
136
+ ```bash
137
+ git clone https://github.com/wachawo/wtftools
138
+ cd wtftools
139
+ pip install -e .
140
+ python3 wtf.py audit # or run it without installing
141
+ ```
142
+
143
+ ## License
144
+
145
+ MIT
@@ -1,5 +1,6 @@
1
1
  # bash completion for `wtf` / `wtftools`
2
- # Install: copy to /etc/bash_completion.d/ or `source` from your bashrc.
2
+ # Enable: eval "$(wtf completion bash)" (add that line to ~/.bashrc),
3
+ # or copy this script to /etc/bash_completion.d/wtf
3
4
 
4
5
  _wtf_complete() {
5
6
  local cur prev cmd
@@ -7,8 +8,8 @@ _wtf_complete() {
7
8
  cur="${COMP_WORDS[COMP_CWORD]}"
8
9
  prev="${COMP_WORDS[COMP_CWORD-1]}"
9
10
 
10
- local subcommands="info audit problems crontab doctor services config logs explain history diff top ports events"
11
- local global_opts="-h --help -V --version --no-color -v --verbose -q --quiet --config"
11
+ local subcommands="info disk cpu mem net io who temp temps temperature daily audit problems crontab doctor services service config logs explain history diff top ports port docker events completion"
12
+ local global_opts="-h --help -V --version -f --format --no-color -v --verbose -q --quiet --config"
12
13
 
13
14
  if [[ $COMP_CWORD -eq 1 ]]; then
14
15
  COMPREPLY=( $(compgen -W "$subcommands $global_opts" -- "$cur") )
@@ -20,8 +21,36 @@ _wtf_complete() {
20
21
  case "$cmd" in
21
22
  info)
22
23
  COMPREPLY=( $(compgen -W "--format" -- "$cur") )
24
+ [[ "$prev" == "--format" ]] && COMPREPLY=( $(compgen -W "text plain json" -- "$cur") )
25
+ ;;
26
+ daily)
27
+ COMPREPLY=( $(compgen -W "--since --ignore --strict --exit-zero --format" -- "$cur") )
23
28
  [[ "$prev" == "--format" ]] && COMPREPLY=( $(compgen -W "text json" -- "$cur") )
24
29
  ;;
30
+ disk)
31
+ local opts="--tree --depth --top --format --show-commands"
32
+ case "$prev" in
33
+ --format) COMPREPLY=( $(compgen -W "text plain json" -- "$cur") ); return 0 ;;
34
+ --tree|--depth|--top) return 0 ;;
35
+ esac
36
+ if [[ "$cur" == -* ]]; then
37
+ COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
38
+ else
39
+ COMPREPLY=( $(compgen -d -- "$cur") ) # a PATH to break down
40
+ fi
41
+ ;;
42
+ cpu|net|io)
43
+ COMPREPLY=( $(compgen -W "--format --show-commands" -- "$cur") )
44
+ [[ "$prev" == "--format" ]] && COMPREPLY=( $(compgen -W "text plain json" -- "$cur") )
45
+ ;;
46
+ mem|who)
47
+ COMPREPLY=( $(compgen -W "--since --format --show-commands" -- "$cur") )
48
+ [[ "$prev" == "--format" ]] && COMPREPLY=( $(compgen -W "text plain json" -- "$cur") )
49
+ ;;
50
+ temp|temps|temperature)
51
+ COMPREPLY=( $(compgen -W "--format" -- "$cur") )
52
+ [[ "$prev" == "--format" ]] && COMPREPLY=( $(compgen -W "text plain json" -- "$cur") )
53
+ ;;
25
54
  audit|problems)
26
55
  local opts="--format --strict --exit-zero --check --only --since --list-checks --brief -b --ignore --serial --check-timeout --alert --alert-on --save --output -o"
27
56
  case "$prev" in
@@ -72,23 +101,30 @@ updates reboot cron-daemon crontab docker hw-temp smart dns http-probes tcp-prob
72
101
  local opts="--sort --limit --user --name --format"
73
102
  case "$prev" in
74
103
  --sort) COMPREPLY=( $(compgen -W "cpu rss" -- "$cur") ); return 0 ;;
75
- --format) COMPREPLY=( $(compgen -W "text json" -- "$cur") ); return 0 ;;
104
+ --format) COMPREPLY=( $(compgen -W "text plain json" -- "$cur") ); return 0 ;;
76
105
  --user) COMPREPLY=( $(compgen -u -- "$cur") ); return 0 ;;
77
106
  esac
78
107
  COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
79
108
  ;;
80
- ports)
109
+ ports|port)
81
110
  local opts="--proto --public-only --format"
82
111
  case "$prev" in
83
112
  --proto) COMPREPLY=( $(compgen -W "tcp udp all" -- "$cur") ); return 0 ;;
84
- --format) COMPREPLY=( $(compgen -W "text json" -- "$cur") ); return 0 ;;
113
+ --format) COMPREPLY=( $(compgen -W "text plain json" -- "$cur") ); return 0 ;;
85
114
  esac
86
115
  COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
87
116
  ;;
88
- services)
117
+ docker)
118
+ case "$prev" in
119
+ --format) COMPREPLY=( $(compgen -W "text plain json" -- "$cur") ); return 0 ;;
120
+ esac
121
+ local names=$(docker ps --format '{{.Names}}' 2>/dev/null)
122
+ COMPREPLY=( $(compgen -W "--format $names" -- "$cur") )
123
+ ;;
124
+ services|service)
89
125
  local opts="-n --lines --format"
90
126
  case "$prev" in
91
- --format) COMPREPLY=( $(compgen -W "text json" -- "$cur") ); return 0 ;;
127
+ --format) COMPREPLY=( $(compgen -W "text plain json" -- "$cur") ); return 0 ;;
92
128
  esac
93
129
  local units=$(systemctl list-units --type=service --no-legend --plain 2>/dev/null \
94
130
  | awk '{ sub(/\.service$/, "", $1); print $1 }')
@@ -98,14 +134,14 @@ updates reboot cron-daemon crontab docker hw-temp smart dns http-probes tcp-prob
98
134
  local opts="--since --kind --limit --format"
99
135
  case "$prev" in
100
136
  --kind) COMPREPLY=( $(compgen -W "reboot oom failed-unit kernel-err auth-fail login" -- "$cur") ); return 0 ;;
101
- --format) COMPREPLY=( $(compgen -W "text json" -- "$cur") ); return 0 ;;
137
+ --format) COMPREPLY=( $(compgen -W "text plain json" -- "$cur") ); return 0 ;;
102
138
  esac
103
139
  COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
104
140
  ;;
105
141
  logs)
106
142
  local opts="--since --priority -p --units --lines -n --format"
107
143
  case "$prev" in
108
- --format) COMPREPLY=( $(compgen -W "text json" -- "$cur") ); return 0 ;;
144
+ --format) COMPREPLY=( $(compgen -W "text plain json" -- "$cur") ); return 0 ;;
109
145
  --priority|-p) COMPREPLY=( $(compgen -W "emerg alert crit err warning notice info debug" -- "$cur") ); return 0 ;;
110
146
  esac
111
147
  COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
@@ -127,6 +163,9 @@ updates reboot cron-daemon crontab docker hw-temp smart dns http-probes tcp-prob
127
163
  COMPREPLY=( $(compgen -W "--example --format" -- "$cur") )
128
164
  [[ "$prev" == "--format" ]] && COMPREPLY=( $(compgen -W "text json" -- "$cur") )
129
165
  ;;
166
+ completion)
167
+ COMPREPLY=( $(compgen -W "bash zsh" -- "$cur") )
168
+ ;;
130
169
  esac
131
170
  }
132
171