MangoHud logs one GPU. On a hybrid box (discrete NVIDIA/AMD beside an AMD/Intel iGPU) its default often latches onto the idle iGPU, so every gpu_* column reads ~0 while the discrete card does the rendering. Detect the actual gaming GPU — any vendor, single- or multi-GPU — and pin it via gpu_list. Selection: single GPU -> that one; discrete NVIDIA preferred; otherwise the card with the most VRAM. Override with MANGOHUD_LOGGER_GPU. Verified against MangoHud's own enumeration (gpu_list=0 -> renderD128, RTX 5060 Ti) and 7 synthetic layouts incl. NVIDIA as the second node. Also make CPU telemetry work across AMD and Intel. cpu_power was logging 0 because the RAPL energy counters are root-only since CVE-2020-8694 (same intel-rapl powercap path on both vendors). Add: - doctor: read-only GPU/CPU telemetry readiness report - fix-cpu-power: install a udev rule making RAPL counters user-readable - enable-time warnings pointing at the fix CPU temp already works via hwmon (k10temp/zenpower/coretemp). Default no-arg behavior (toggle on/off) is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
255 lines
10 KiB
Markdown
Executable file
255 lines
10 KiB
Markdown
Executable file
# mangohud-logger
|
|
|
|
One-touch toggle for MangoHud CSV logging on Linux gaming-launcher systems
|
|
(SteamOS Game Mode, DeckShift, super-alt-S, plain `gamescope-session-plus`, or
|
|
any setup that already uses MangoHud).
|
|
|
|
Run the script — it switches logging on if it's off, off if it's on. CSV
|
|
samples land in `~/Downloads/mango-logs/`. That's the entire interface.
|
|
|
|
## Why this exists
|
|
|
|
Getting MangoHud to *actually* write logs from a Steam-via-gamescope game
|
|
turns out to be a multi-step setup, and every step has a non-obvious gotcha.
|
|
Worse, the *right* setup differs depending on which gamescope session manager
|
|
your distro ships. This script detects that and handles it so you don't have to.
|
|
|
|
## What it changes
|
|
|
|
The script writes marker-tagged files (so it can clean them up on disable, and
|
|
won't trample anything you wrote by hand):
|
|
|
|
1. **`~/.config/MangoHud/MangoHud.conf`** — appends a marker-bracketed block
|
|
with `output_folder`, `autostart_log=1`, `log_duration=0` (= until you
|
|
quit), `log_interval=100`, `toggle_logging=Shift_L+F2`, a `no_display=0`
|
|
override, and a `gpu_list=<index>` pin (see [GPU selection](#gpu-selection)).
|
|
(Also serves as the on/off state marker.)
|
|
|
|
2. **`~/.config/environment.d/95-mangohud-logger.conf`** — contains:
|
|
- `MANGOHUD=1` so the Vulkan loader auto-injects MangoHud into every game.
|
|
- `MANGOHUD_CONFIG=<inline copy of the logging keys>`. This is the important
|
|
one for SteamOS Game Mode — see [Game Mode](#steamos-game-mode) below.
|
|
|
|
Requires a logout/login to take effect (systemd-user only reads
|
|
`environment.d/*.conf` at session start).
|
|
|
|
3. **`~/.config/gamescope-session-plus/sessions.d/steam`** — *only written on
|
|
the `gamescope-session-plus` session flavor* (see flavor detection below).
|
|
A user-level override that unsets the system's `MANGOHUD_CONFIGFILE` and
|
|
turns off `STEAM_USE_MANGOAPP`. Not written on stock SteamOS.
|
|
|
|
When you toggle it off, the script removes everything it wrote.
|
|
|
|
## GPU selection
|
|
|
|
MangoHud logs stats for **one** GPU. On a hybrid machine — a discrete
|
|
NVIDIA/AMD card alongside an AMD/Intel iGPU (common on modern AMD desktops,
|
|
laptops, and handhelds) — MangoHud's default frequently latches onto the *idle*
|
|
iGPU, so every `gpu_*` column in the CSV reads ~0 (0 % load, idle clocks, idle
|
|
power) even while the discrete card does all the rendering.
|
|
|
|
On enable, the script auto-detects the GPU that's actually rendering games and
|
|
pins MangoHud to it with `gpu_list=<index>`. It's **vendor-agnostic**:
|
|
|
|
- **Single GPU** (any vendor) → that GPU.
|
|
- **Discrete NVIDIA** present → the NVIDIA card.
|
|
- **Two AMD/Intel GPUs** → the one with the most VRAM (the discrete card;
|
|
iGPUs report little or none).
|
|
|
|
It works by mapping DRM render nodes (`renderD128`, `renderD129`, …) to
|
|
MangoHud's `gpu_list` index order. The chosen GPU is printed on enable:
|
|
|
|
```
|
|
:: gpu logged: gpu_list=0 → renderD128 (NVIDIA), 2 GPU(s) detected
|
|
```
|
|
|
|
If the guess is wrong, override it:
|
|
|
|
```bash
|
|
MANGOHUD_LOGGER_GPU=amd ./mangohud-logger.sh # or: nvidia | intel
|
|
MANGOHUD_LOGGER_GPU=1 ./mangohud-logger.sh # or an explicit gpu_list index
|
|
```
|
|
|
|
> **NVIDIA note:** MangoHud reads NVIDIA load/power/clocks via NVML. If NVML
|
|
> (`libnvidia-ml`, shipped with `nvidia-utils`) is missing, the script warns you
|
|
> — without it the NVIDIA `gpu_*` columns stay at 0.
|
|
|
|
## Session-flavor detection
|
|
|
|
Game Mode is launched differently on different distros, and the fix differs
|
|
too. On enable, the script detects which one you have (`detect_gs_flavor`):
|
|
|
|
| Flavor | Detected by | What the script does |
|
|
|--------|-------------|----------------------|
|
|
| `plus` | `/usr/share/gamescope-session-plus/sessions.d/steam` exists | Writes the `sessions.d/steam` override (file #3). |
|
|
| `steamos` | `/usr/lib/steamos/gamescope-session` exists | Skips file #3; relies on `MANGOHUD_CONFIG` (file #2). See below. |
|
|
| `none` | neither | Desktop-only; `MANGOHUD=1` is enough for Vulkan games. |
|
|
|
|
## SteamOS Game Mode
|
|
|
|
Stock SteamOS (e.g. 3.x "holo") launches Game Mode via
|
|
`/usr/lib/steamos/gamescope-session`, **not** `gamescope-session-plus`. That
|
|
session script unconditionally does:
|
|
|
|
```bash
|
|
export STEAM_USE_MANGOAPP=1
|
|
export MANGOHUD_CONFIGFILE="$tmpdir/mangohud.config" # written with just "no_display"
|
|
```
|
|
|
|
and it **sources no user override file** — so the old `sessions.d/steam` trick
|
|
does nothing here, and you can't override `STEAM_USE_MANGOAPP` from
|
|
`environment.d` (the session exports it afterwards).
|
|
|
|
**How logging actually works here:** the on-screen overlay in Game Mode is
|
|
**mangoapp** (a compositor overlay), and mangoapp *is* MangoHud — it can write
|
|
CSV logs itself. Steam launches mangoapp with your systemd user environment, so
|
|
it inherits the `MANGOHUD_CONFIG` from file #2. `MANGOHUD_CONFIG` takes
|
|
precedence over the session's `no_display` `MANGOHUD_CONFIGFILE`, so mangoapp
|
|
picks up `autostart_log`/`output_folder` and logs every game — **no per-game
|
|
launch options needed.**
|
|
|
|
Notes:
|
|
- Logs are named **`mangoapp_<timestamp>.csv`** (the logger is mangoapp, not the
|
|
in-game layer), so a file spans a Game Mode session rather than one-per-game.
|
|
- **You must fully restart into Game Mode once after enabling** (log out/in or
|
|
reboot) so mangoapp inherits `MANGOHUD_CONFIG`. If you enable while already in
|
|
Game Mode, that session won't have it and nothing logs.
|
|
- Verified on SteamOS 3.9 with MangoHud 0.8.3-rc1: a Proton game (DREDGE) in
|
|
Game Mode produced a 1039-row `mangoapp_*.csv` of real fps/frametime data.
|
|
|
|
**Per-game fallback** (if you don't want to restart the session, or want the
|
|
in-game Vulkan layer instead of mangoapp): set this in a game's
|
|
*Steam → Properties → Launch Options*:
|
|
|
|
```
|
|
MANGOHUD_CONFIGFILE=$HOME/.config/MangoHud/MangoHud.conf mangohud %command%
|
|
```
|
|
|
|
## Gotchas it works around
|
|
|
|
- **`no_display` blocks `autostart_log`.** MangoHud's `autostart_log` rides on
|
|
the render hook that `no_display` disables, so the log never starts. The
|
|
script's block ends with `no_display=0`. Tradeoff: while logging is on, the
|
|
HUD is visible during games.
|
|
|
|
- **The system session forces a `no_display` config file.** Both session
|
|
flavors export `MANGOHUD_CONFIGFILE` pointing at a temp file containing only
|
|
`no_display`, which would suppress your real config. On `plus` the script
|
|
unsets that var; on `steamos` the `MANGOHUD_CONFIG` env var overrides it.
|
|
|
|
- **Steam uses `mangoapp` instead of the in-game Vulkan layer in Game Mode.**
|
|
`STEAM_USE_MANGOAPP=1`. On `steamos` you can't turn this off globally — so the
|
|
script leans into it and lets mangoapp do the logging (see above). On `plus`
|
|
the override sets `STEAM_USE_MANGOAPP=0` to use the in-game layer.
|
|
|
|
- **`log_duration=0` means "log forever".** Empirically `0` = log until you quit
|
|
or hit the toggle key.
|
|
|
|
- **`MANGOHUD=1` only injects the Vulkan layer.** OpenGL-only games still need
|
|
`mangohud %command%` in Steam launch options or an `LD_PRELOAD` wrapper.
|
|
|
|
## Install
|
|
|
|
Requires `mangohud` (and `lib32-mangohud` for 32-bit games). On Arch / SteamOS:
|
|
|
|
```bash
|
|
sudo pacman -S mangohud lib32-mangohud
|
|
```
|
|
|
|
Then:
|
|
|
|
```bash
|
|
git clone https://github.com/28allday/mangohud-logger-steamos.git
|
|
cd mangohud-logger-steamos
|
|
chmod +x mangohud-logger.sh
|
|
./mangohud-logger.sh
|
|
```
|
|
|
|
Or copy the script anywhere on `$PATH`:
|
|
|
|
```bash
|
|
install -Dm755 mangohud-logger.sh ~/.local/bin/mangohud-logger
|
|
mangohud-logger
|
|
```
|
|
|
|
## Usage
|
|
|
|
```bash
|
|
./mangohud-logger.sh # toggle logging on/off (default)
|
|
./mangohud-logger.sh doctor # report GPU/CPU telemetry readiness (no changes)
|
|
./mangohud-logger.sh fix-cpu-power # make RAPL CPU-power counters readable (sudo)
|
|
./mangohud-logger.sh help # usage
|
|
```
|
|
|
|
Run with no argument to toggle: first run enables, second disables. After the
|
|
first enable, **log out and back in** (Game Mode users: fully restart into Game
|
|
Mode) so the env vars become effective. You only need to do that once.
|
|
|
|
Before your first benchmark, run `doctor` — it tells you exactly which columns
|
|
will hold real data and what (if anything) needs fixing:
|
|
|
|
```
|
|
:: GPUs (DRM render nodes):
|
|
renderD128 (NVIDIA)
|
|
renderD129 (AMD)
|
|
✓ will log: gpu_list=0 → renderD128 (NVIDIA), 2 GPU(s) detected
|
|
✓ NVML present → NVIDIA load/power/clocks will log
|
|
:: CPU: AMD
|
|
✓ temp source: hwmon 'k10temp' → cpu_temp will log
|
|
! power (RAPL): root-only → cpu_power = 0. Fix: mangohud-logger.sh fix-cpu-power
|
|
```
|
|
|
|
In-game keys (set by the script's MangoHud block):
|
|
|
|
| Key | Action |
|
|
|---|---|
|
|
| `Shift+F2` | Toggle logging on/off mid-game |
|
|
| Your existing `toggle_hud` key | Hide the HUD overlay (logging keeps running) |
|
|
|
|
CSV files appear in `~/Downloads/mango-logs/`. Drop them into
|
|
<https://flightlessmango.com/> for graphs, or open in a spreadsheet.
|
|
|
|
## CPU power (`cpu_power` column reads 0?)
|
|
|
|
MangoHud reads CPU package power from the RAPL powercap energy counters. Since
|
|
CVE-2020-8694 those counters are **root-only** (mode `0400`), so user-mode
|
|
MangoHud can't read them and `cpu_power` logs as `0`. This is the same on **AMD
|
|
and Intel** — the powercap interface is named `intel-rapl` on both (it's the
|
|
framework name; on AMD `intel_rapl_msr` feeds it from the Zen RAPL MSRs).
|
|
|
|
`fix-cpu-power` installs a udev rule
|
|
(`/etc/udev/rules.d/60-mangohud-logger-rapl.rules`) that makes `energy_uj`
|
|
user-readable, and applies it immediately:
|
|
|
|
```bash
|
|
./mangohud-logger.sh fix-cpu-power
|
|
```
|
|
|
|
> **Security note:** this re-exposes the low-severity PLATYPUS power
|
|
> side-channel. Fine for a personal gaming/benchmark box; skip it on shared or
|
|
> multi-user machines. Remove the rule file to revert.
|
|
|
|
CPU **temperature** needs no fix — it comes from hwmon (`k10temp`/`zenpower` on
|
|
AMD, `coretemp` on Intel) and works out of the box.
|
|
|
|
## Compatibility
|
|
|
|
- **SteamOS Game Mode** (`/usr/lib/steamos/gamescope-session`) — logs via
|
|
mangoapp; see [Game Mode](#steamos-game-mode).
|
|
- **DeckShift** ([28allday/DeckShift](https://github.com/28allday/DeckShift))
|
|
— gamescope-session-plus based.
|
|
- **super-alt-S** ([28allday/super-alt-S-cachy-deckmode](https://github.com/28allday/super-alt-S-cachy-deckmode))
|
|
— KDE-Plasma gaming mode on CachyOS.
|
|
- **Plain `gamescope-session-plus`** on any Arch-based distro.
|
|
- **Steam without gamescope** — works too; the gamescope override becomes a no-op.
|
|
- **Non-systemd distros** — the `environment.d` file won't be read; set
|
|
`MANGOHUD=1` (and `MANGOHUD_CONFIG`) via your distro's env-var mechanism.
|
|
|
|
## Honours XDG
|
|
|
|
Log folder is `$XDG_DOWNLOAD_DIR/mango-logs` (resolved via `xdg-user-dir`),
|
|
config dir is `$XDG_CONFIG_HOME` — works on non-English locales.
|
|
|
|
## License
|
|
|
|
MIT
|