Skip to content
/ whox Public

A “who-like” report that unifies session signals with per-user CPU%, Memory%, and Tasks, plus optional socket-to-host mapping

License

Notifications You must be signed in to change notification settings

ncsa/whox

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

whox (who-extended)

A fast, one-line-per-user “who-like” report that unifies session signals (TTY and non‑TTY) with per-user CPU%, Memory%, and Tasks, plus optional socket-to-host mapping. Designed for RHEL, SLES, and Ubuntu environments—especially HPC/login nodes and shared multi-user servers.

Key Features

  • Unified session view: combines
    • TTY sessions (who, SSH interactive)
    • Non‑TTY activity (SSH non‑tty, SFTP, VSCode Remote, Jupyter, RStudio Server, FTP, Samba, NoMachine)
    • tmux (attached/detached), mosh
  • Resource metrics per user:
    • CPU% — sum of %CPU across processes (multi-core aware, can exceed 100%)
    • MEM% — sum of RSS vs MemTotal (fast; note shared pages caveat)
    • TASKS — process count
  • Host mapping (optional) via ss -tnp on common service ports (e.g., 22, 8787, 445, etc.)
  • Smart WHEN selection:
    • Uses earliest/latest session time by default
    • Falls back to earliest/latest “interesting” process start for users with processes but no session signals
    • Adds proc(<program>) hint to WHAT on process-based fallback
  • Robust & efficient:
    • Single ps snapshot (user pid ppid etimes %CPU RSS cmd)
    • Single ss pass
    • Hardened temp handling, numeric/input validation, and minimal process spawning
  • Clean output:
    • Columns: USER, TTY, WHEN, HOST, CPU%, MEM%, TASKS, WHAT
    • Any missing field prints as -

Why this exists

Stock who primarily reports interactive sessions (terminal lines). On shared servers and HPC login nodes, many users run workloads through non-interactive channels (SFTP, VSCode Remote, Jupyter, Slurm‑launched shells, etc.). This tool surfaces all active users and associates signals, giving operators a clear, sortable snapshot.

Requirements

  • Bash 4+ (associative arrays)
  • ps (procps‑ng)
  • ss (iproute2) — optional, for host mapping
  • who, date, awk, stat, column (optional for pretty printing), tmux (optional)
  • Linux (tested on RHEL, SLES, Ubuntu)

Installation

git clone https://github.com/ncsa/whox.git
cd whox
sudo install -m 0755 scripts/whox.sh /usr/local/bin/whox

Or run in place:

chmod +x whox.sh
./whox.sh

Usage

# Default: latest per-user time, columnized output
whox.sh

# Earliest per-user time
whox.sh --sort earliest

# Raw tab output for pipelines (no column formatting, no header)
whox.sh --no-column --no-header

# Treat UID < 500 as system accounts (default is 1000)
whox.sh --sys-uid-max 500

Output columns

  • USER — login name
  • TTYpts/N or ttyN if interactive; mixed if both TTY/non‑TTY; notty if only non‑TTY; - otherwise
  • WHEN — per-user earliest/latest time; if no session signals, uses earliest/latest process start
  • HOST — single host if resolvable, or multiple(N) if several; - if unknown
  • CPU% — sum of %CPU (multi-core aware)
  • MEM% — sum of RSS / MemTotal
  • TASKS — number of processes per user
  • WHAT — aggregated signals, e.g. tty(1),ssh(2),vscode(5),jupyter(1),proc(salloc)

Example

USER      TTY     WHEN              HOST            CPU%  MEM%  TASKS  WHAT
user1     pts/21  2025-12-05 10:24  192.0.2.2       0.00  0.04  4      tty(1),ssh(1)
user2     notty   2025-12-05 10:23  -               6.10  4.68  22     ssh-non-tty(1),vscode(13)
user3     -       2025-12-05 00:53  -               0.00  0.04  5      proc(salloc)
user4     -       2025-12-05 10:42  -               0.10  0.49  4      proc(python)
user5     pts/34  2025-12-05 10:44  192.0.2.6       2.40  1.15  562    tty(1),ssh(1)

Options

  • --sort earliest|latest
    Controls whether WHEN (and sorting key) uses each user’s earliest or latest signal (or process fallback).

  • --sys-uid-max N
    Consider UID < N as “system accounts.” If a user has no session signals and is a system account, their row is suppressed. Default 1000.

  • --no-header
    Don’t print the header line.

  • --no-column
    Don’t format with column -t; useful for machine parsing.

Performance

  • Single pass ps snapshot with PPID & ETIMES—no repeated ps scans.
  • No per-PID ps calls except rare fallback when etimes is absent.
  • One ss -tnp pass to map PID → remote host for common service ports.
  • LC_ALL=C for faster text processing, and umask 077 + private TMPDIR for secure temporary files.

Security & Hardening

  • Least privilege: runs fine as non‑root. Root improves tmux cross-user visibility and socket mapping; prefer constrained sudo rules if needed.
  • Input validation: numeric checks for PIDs, whitelist for usernames, -- passed to commands to avoid option injection.
  • Temp isolation: mktemp -d with trap cleanup, restricted permissions.
  • Systemd (optional): set NoNewPrivileges=true, PrivateTmp=true, and run under a dedicated user for scheduled reports.

Caveats

  • CPU% is summed from per-process %CPU; on multi-core hosts, totals can exceed 100%.
  • MEM% uses RSS; shared pages may be double-counted (as with most quick summaries).
  • Host mapping is limited to known service ports; customize as needed.
  • Threads are not counted (TASKS = processes). A future flag can add thread counts.

Troubleshooting

  • Blank fields: the script prints - for any unavailable field; if you see - for HOST, ss may not have captured relevant sockets or ports.
  • Unbound variable errors: the script uses set -u; ensure variable names are correct if you customize it.
  • Syntax check: run bash -n whox.sh after edits.
  • ShellCheck: shellcheck -x whox.sh for static analysis.

Roadmap / Ideas

  • --json output mode for ingestion by monitoring/SEIM tools
  • --threads to report per-user thread count
  • --cgroup mode (RHEL 9.x) to read memory.current, pids.current, and cgroup CPU limits from user.slice
  • Configurable regexes: --proc-hint-include and --proc-hint-exclude

Contributing

Issues and PRs welcome! Please:

  1. Keep changes portable across RHEL/SLES/Ubuntu.
  2. Add bash -n and shellcheck to your PR checks.
  3. Include a short before/after performance note for changes affecting runtime.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Author Information

This role was created by NCSA's ICI team. https://www.ncsa.illinois.edu/

About

A “who-like” report that unifies session signals with per-user CPU%, Memory%, and Tasks, plus optional socket-to-host mapping

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages