Skip to main content

ubuntu-doctor

Read-only diagnostic CLI for Ubuntu systems, with explained findings and stable JSON output.

CI License: MIT

Problem

When an Ubuntu machine slows down or misbehaves, the first diagnosis is always the same sequence of manual commands: df -h, free -h, systemctl --failed, ss -tulpn, scanning /var/log, checking for broken packages. It is repetitive, easy to miss a step, and the results end up scattered across several outputs with no interpretation.

ubuntu-doctor runs those checks for you and returns a prioritized, explained report: what is critical, what is a warning, what is healthy — each finding with a suggested next step. It is read-only by design and never changes the system.

Features

  • Disk usage per mount point (snap/pseudo filesystems excluded)
  • Memory and swap, judged by available memory
  • CPU load average and the heaviest processes (by name, no command lines)
  • Failed systemd units
  • Listening TCP/UDP ports, with owning process where visible
  • Oversized log files under /var/log
  • Broken packages and pending (security) updates
  • Colored text, stable JSON (a documented contract), and sanitized Markdown output
  • Severity-based exit codes and graceful degradation without privileges

Architecture

See docs/architecture.md. The rule is: collectors don't decide, rules don't collect, renderers don't calculate, and the domain core never touches the OS.

flowchart LR
    CLI[cli.py] --> ORCH[orchestrator]
    ORCH --> COL[collectors]
    COL --> RULES[rules]
    RULES --> FIND[Finding / Report]
    FIND --> REND[render: text / json / markdown]

Requirements

  • Ubuntu 22.04 LTS or newer (Debian-family)
  • Python 3.11+

Installation

Once published, the recommended install is with pipx:

pipx install ubuntu-doctor

From a clone, using uv:

uv sync
uv run ubuntu-doctor --help

Usage

ubuntu-doctor full-check          # run every check and aggregate
ubuntu-doctor disk --json         # a single area, machine-readable
ubuntu-doctor cpu --top 10        # ten heaviest processes
ubuntu-doctor export-report -o report.md

Example full-check output (hostname anonymized):

CRITICAL Failed unit: virtualbox.service  [failed]
         LSB: VirtualBox Linux kernel module
         → Inspect each failed unit with: systemctl status <unit> and
           journalctl -u <unit> -b. ubuntu-doctor never restarts services for you.
UNKNOWN  Broken packages
         Could not determine broken packages: dpkg: ... Permission denied
         → Re-run with sufficient privilege to check: sudo dpkg --audit.
OK       Disk usage: /  [14.6%]
         14.6% used (741.7 GB free of 914.8 GB)
OK       Memory usage  [36.9%]
         36.9% used (14.7 GB available of 23.3 GB); swap 0.0% of 19.7 GB
OK       CPU load  [3.41]
         load average 1.96 / 3.41 / 3.66 on 8 core(s)
OK       Listening ports  [26]
         26 listening ports (17 tcp, 9 udp).

Overall: CRITICAL  (myhost)

Commands

Command Purpose
full-check Run every check and aggregate
disk, memory, cpu, services, network, logs, packages Run a single area
export-report Write a sanitized Markdown report
version Print the version

Common options: --json, --verbose, --config PATH. cpu also takes --top N; export-report takes --output/-o PATH and --force.

Exit codes: 0 no problem · 1 at least one CRITICAL · 2 usage/config error · 3 internal error.

Configuration

Thresholds resolve from three layers, each overriding the previous: defaults → TOML file → environment.

TOML file (via --config PATH, or ~/.config/ubuntu-doctor/config.toml if it exists):

[thresholds]
disk_warn_percent = 80
disk_crit_percent = 90
mem_warn_percent = 85
mem_crit_percent = 95
log_warn_bytes = 104857600      # 100 MB
log_crit_bytes = 1073741824     # 1 GB

Environment variables override the file:

Variable Overrides
UBUNTU_DOCTOR_DISK_WARN / UBUNTU_DOCTOR_DISK_CRIT Disk usage %
UBUNTU_DOCTOR_MEM_WARN / UBUNTU_DOCTOR_MEM_CRIT Memory usage %
UBUNTU_DOCTOR_LOG_WARN / UBUNTU_DOCTOR_LOG_CRIT Log size (bytes)

There are deliberately no --threshold-* flags: the file and environment already cover per-threshold overrides without cluttering every command.

The JSON contract

--json emits a stable object with a schema_version (currently 1). Consumers can rely on the shape; any breaking change bumps schema_version and the package's major version.

Testing

uv run pytest          # 149 tests, 100% coverage, fully offline
uv run ruff check .
uv run mypy

Every test runs offline and deterministically. Command-based checks are tested against real output captured once into tests/fixtures/.

Design decisions

Recorded as ADRs in docs/adr/: pure collectors for testability, psutil over /proc parsing, read-only by design, and threshold/UNKNOWN semantics.

Troubleshooting

  • "Could not determine broken packages: ... Permission denied" — dpkg --audit needs the dpkg lock, which requires privilege. This is expected: the check degrades to UNKNOWN rather than failing. Run sudo dpkg --audit yourself to check.
  • Listening ports show no process — ss cannot name processes owned by other users without privilege. The port is still listed; only the owner is hidden.
  • command not found for a check — on a minimal system systemctl, ss or apt may be absent; that check reports UNKNOWN and the rest still run.

Limitations

  • Ubuntu/Debian only.
  • Read-only: it diagnoses, it never fixes.
  • No history and no continuous monitoring in v1 (each run is a snapshot).
  • File-permission auditing is deliberately omitted (too prone to false positives).
  • Behavior inside containers can differ (cgroup-reported limits).

Roadmap

  • v1.1: Docker container check; snap packaging.
  • v1.2: optional history in SQLite with run-to-run comparison.
  • v2.0: extract the collection layer into a reusable linuxfacts library.

Contributing

Issues and PRs welcome. Please keep the tool read-only, keep tests offline, and run ruff, mypy and pytest before opening a PR. See the issue and PR templates.

License

MIT — see LICENSE.

Contact

David Oliveira · davidoliveira.devbr@gmail.com

Metadata

Release files for ubuntu-doctor 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ubuntu-doctor 1.0.0
File Size Uploaded
ubuntu_doctor-1.0.0.tar.gz 100.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ubuntu-doctor 1.0.0
File Interpreter ABI Platform
ubuntu_doctor-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 132.3 kB

Release files / ubuntu_doctor-1.0.0.tar.gz

Download URL ubuntu_doctor-1.0.0.tar.gz
Size 100.1 kB
Tags Source
SHA-256 checksum
How to use checksums
cddca0f8931f4657372e903785780caf0b0f55716a0f589124c6d6d1787958b1
BLAKE2b-256 checksum
How to use checksums
f6fc62dfc130751304d5ae2548a1eed509ad3919054517b4baf6e6067b412519
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 28, 2026.

Transparency log

Release files / ubuntu_doctor-1.0.0-py3-none-any.whl

Download URL ubuntu_doctor-1.0.0-py3-none-any.whl
Size 32.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a4268e1e4db72e0421bf4e3a261310c992acbcaad6e840c519bfb75f56c57e7b
BLAKE2b-256 checksum
How to use checksums
88fde36a2837528bea53d4c2e5a1ef5f3eab868837321b2188801b6ba7083997
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 28, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page