One-touch MangoHud CSV logging toggle for SteamOS Game Mode (and gamescope-session-plus / DeckShift / super-alt-S). SteamOS variant of mangohud-logger.
Find a file
28allday d2f70296f5 Correct the Shift+F2 claim: the keybind does not work in Game Mode
The in-game keys table told users Shift+F2 toggles logging mid-game. That
holds on the desktop, where the in-game Vulkan layer is the logger, but not
in SteamOS Game Mode: there the logger is mangoapp, which ignores the
keybind. Verified under nested gamescope — the keypress produced no log at
all, while mangohudctl in the same harness started one immediately.

Document mangohudctl as the way to start/stop a log by hand in Game Mode.
It drives mangoapp over a SysV message queue, so it needs no display, no
Wayland socket and no window focus.
2026-07-31 19:09:52 +01:00
.gitignore Support SteamOS Game Mode: global logging via MANGOHUD_CONFIG 2026-06-28 22:29:50 +01:00
LICENSE Support SteamOS Game Mode: global logging via MANGOHUD_CONFIG 2026-06-28 22:29:50 +01:00
mangohud-logger.sh Auto-select the gaming GPU + cross-vendor CPU-power tooling 2026-07-24 19:31:03 +01:00
README.md Correct the Shift+F2 claim: the keybind does not work in Game Mode 2026-07-31 19:09:52 +01:00

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). (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 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/steamonly 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:

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:

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:

sudo pacman -S mangohud lib32-mangohud

Then:

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:

install -Dm755 mangohud-logger.sh ~/.local/bin/mangohud-logger
mangohud-logger

Usage

./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 — desktop only, see below
Your existing toggle_hud key Hide the HUD overlay (logging keeps running)

Shift+F2 does not work in SteamOS Game Mode. There the logger is mangoapp, not the in-game Vulkan layer, and mangoapp ignores the keybind. Verified under nested gamescope: the keypress produced no log at all. To start/stop a log by hand in Game Mode, use mangohudctl (ships with MangoHud), which drives mangoapp over a message queue and needs no display or focus:

mangohudctl set log_session true    # start
mangohudctl set log_session false   # stop (also writes a _summary.csv)

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:

./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.
  • DeckShift (28allday/DeckShift) — gamescope-session-plus based.
  • super-alt-S (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