spacetrace
DE
Download

Handbuch

Alles, was das Kommandozeilenwerkzeug kann, in der Reihenfolge, in der Sie es wahrscheinlich brauchen. --help bei jedem Befehl gibt dasselbe ohne Browser aus.

Erster Scan

Ein Scan läuft einen Ordner durch und gibt aus, was er gefunden hat. Nichts wird gespeichert, nichts verändert.

$ spacetrace scan ~/projects
scanned 84,213 entries in 1.9s
total 12.4 GiB logical · 12.7 GiB on disk
3 paths could not be read

Unlesbare Pfade werden gezählt und stichprobenartig gezeigt, statt den Durchlauf abzubrechen. Unter macOS braucht der Weg aus Ihrem persönlichen Ordner heraus Full Disk Access für das Terminal; ohne das läuft der Scan trotzdem durch und sagt, was er nicht gesehen hat.

Schneller und enger machen

spacetrace scan / -x
spacetrace scan ~/code --exclude node_modules --exclude .git
spacetrace scan /var --depth 3
spacetrace scan /srv --no-dedupe

--exclude nimmt einen Verzeichnisnamen, keinen Pfad, und lässt sich wiederholen. In ausgeschlossene Ordner wird nie hineingegangen: node_modules auf einer Entwicklungsmaschine auszuschließen ist meist der Unterschied zwischen zwei und dreißig Sekunden.

Momentaufnahmen und Vergleich

Das ist der Teil, den andere Analysatoren nicht haben. Einen Scan speichern, später noch einen, und fragen, was sich dazwischen verändert hat.

$ spacetrace scan /srv --save --label weekly
saved snapshot #1

$ spacetrace scans
 ID  WHEN              HOST     ROOT   LABEL    TOTAL
  2  2026-09-06 19:40  srv-01   /srv            76.3 MiB
  1  2026-09-06 17:23  srv-01   /srv   weekly   23.8 MiB

Dann vergleichen. Ohne Argumente nimmt es die letzten beiden.

$ spacetrace diff --path /srv
#1 2026-09-06 17:23 [weekly]  →  #2 2026-09-06 19:40
total 23.8 MiB → 76.3 MiB   (+52.5 MiB)

      CHANGE  STATUS          NEW  PATH
   +40.1 MiB  grew       42.9 MiB  app/logs/
   +14.3 MiB  grew       25.7 MiB  backups/
    -1.9 MiB  removed         0 B  uploads/
Warum es den tiefsten Ordner nennt

Ein Ordner, dessen Wachstum vollständig von einem einzigen Kind kommt, sagt Ihnen nichts Neues und wird deshalb übersprungen. Der Bericht nennt die erste Ebene, auf der sich die Veränderung wirklich verteilt — den Verursacher, nicht seine Vorfahren.

Gegen die Platte, wie sie jetzt ist

Sie brauchen keine zwei Momentaufnahmen. Vergleichen Sie die neueste mit einem laufenden Scan:

spacetrace diff --since-last /srv

Auswählen, was erscheint

spacetrace diff --path /srv --min 10M
spacetrace diff --path /srv --files
spacetrace diff 3 7

Die Datenbank nicht unendlich wachsen lassen

spacetrace prune --path /srv --keep 30
spacetrace rm 4

Einen Scan durchsehen

ls listet Ordner nach Größe — aus einem laufenden Scan oder aus einer gespeicherten Momentaufnahme.

spacetrace ls /var/lib --top 20
spacetrace ls --scan 3 --subpath docker/overlay2

Um eine Momentaufnahme an etwas anderes zu geben, schreibt export das Format von ncdu:

spacetrace export --scan 3 --out scan.json && ncdu -f scan.json

Jeder Befehl nimmt außerdem --json, und das ist der unterstützte Weg, darauf zu skripten. Die menschenlesbaren Spalten dürfen sich ändern, die Form des JSON nicht.

Der Agent auf einem Server

spacetrace-agent ist derselbe Code als Dienst: er scannt die konfigurierten Wurzeln nach Zeitplan, bewahrt die Momentaufnahmen auf und antwortet über HTTP. Eine statische Binärdatei — und er liest nur; es gibt in ihm keinen Codeweg, der außerhalb seiner eigenen Momentaufnahmen-Datenbank etwas löscht.

  1. Konfiguration und Token schreiben

    spacetrace-agent init > /etc/spacetrace/agent.toml
    head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \n' > /etc/spacetrace/token && chmod 600 /etc/spacetrace/token

    serve startet ohne Token nicht. Ein Agent ohne Authentifizierung übergibt sein gesamtes Dateisystem-Inventar an jeden, der den Port erreicht.

  2. Sagen, was wann gescannt wird

    db = "/var/lib/spacetrace/snapshots.sqlite"
    utc_offset_minutes = 0
    
    [server]
    listen = "127.0.0.1:7878"
    token_file = "/etc/spacetrace/token"
    
    [[roots]]
    path = "/var"
    schedule = "0 3 * * *"
    label = "nightly"
    exclude = ["node_modules", ".git"]
    one_file_system = true
    keep = 14

    Fünf Cron-Felder, mit *, a-b, */n und Listen. Keine Sekunden, kein @daily. Unbekannte Konfigurationsschlüssel werden beim Start abgelehnt, denn ein Tippfehler, der auf einer unbeobachteten Maschine stillschweigend nichts tut, ist schlimmer als eine Startverweigerung.

  3. Vor dem Start prüfen

    $ spacetrace-agent --config /etc/spacetrace/agent.toml check
    config       ok
    database     /var/lib/spacetrace/snapshots.sqlite
    host         nas
    listen       127.0.0.1:7878
    token        configured
    ad-hoc scans refused
    
    ROOT                          SCHEDULE        NEXT RUN
    /var                          0 3 * * *       2026-09-09 03:00
    
    Times are UTC.

    Ein Zeitplan, der nie auslösen kann, meldet never statt still zu scheitern.

  4. Starten

    systemctl enable --now spacetrace-agent

    Die mitgelieferte systemd-Unit führt den Agenten als eigenen unprivilegierten Benutzer mit ProtectSystem=strict aus, mit Nice=10 und Idle-E/A-Priorität. Ein Scan darf nie dem in den Weg kommen, wofür die Maschine eigentlich da ist.

    In Docker den Host schreibgeschützt einhängen und den scannen:

    docker run -d --name spacetrace \
      -v /:/host:ro \
      -v spacetrace-data:/var/lib/spacetrace \
      -v /etc/spacetrace:/etc/spacetrace:ro \
      -p 7878:7878 \
      ghcr.io/unalcakir28/spacetrace

Bevor Sie ihn nach außen geben

  • Er lauscht standardmäßig auf Loopback. Ein Dateisystem-Inventar in ein Netz zu stellen, muss eine bewusste Änderung sein.
  • Im Agenten gibt es kein TLS. Setzen Sie einen Reverse Proxy davor.
  • Das Token wird ohne vorzeitigen Abbruch verglichen: ein falsches Token braucht gleich lange zur Ablehnung, egal wie viel davon richtig war.
  • /health braucht kein Token, damit ein Container-Healthcheck funktioniert, und gibt nur Status und Version zurück — keinen Hostnamen, keine Wurzeln.
  • Scans auf Zuruf sind aus. Eingeschaltet kann jeder mit dem Token jedes Verzeichnis auflisten, das der Benutzer des Agenten lesen darf.

Eine andere Maschine lesen

Jeder lesende Befehl nimmt --remote. Es ist nichts Neues zu lernen: dieselben Unterbefehle, nur woanders hin gerichtet.

export SPACETRACE_TOKEN=…

spacetrace --remote https://nas.example.com scans
spacetrace --remote https://nas.example.com diff --path /var
spacetrace --remote https://nas.example.com ls --top 20
spacetrace --remote https://nas.example.com pull --root /var

Speichern Sie ein Ziel, damit URL und Token nicht mehr getippt werden müssen — in ~/.config/spacetrace/remotes.toml:

[remotes.nas]
url = "https://nas.example.com"
token = "…"
Eine entfernte Momentaufnahme ist nichts anderes

Was über die Leitung kommt, ist dieselbe eigenständige SQLite-Datei, die der Agent aufbewahrt: auflisten, durchsehen und vergleichen läuft mit genau demselben Code wie bei einer lokalen. Sie können das Werkzeug auch ganz weglassen und trotzdem eine Datei bekommen, die Sie öffnen können:

curl -H "Authorization: Bearer $SPACETRACE_TOKEN" \
  https://nas.example.com/scans/7/download -o snap.sqlite
spacetrace --db snap.sqlite scans

scan, prune und rm verweigern sich mit --remote: sie arbeiten auf lokalem Zustand, und der Agent löscht nichts.

Welche Größe, und warum

Jeder Eintrag trägt zwei Zahlen, und keine ist eine Schätzung der anderen.

MaßWas es istStimmt überein mit
logischDie Länge, die jede Datei angibtdu -sb
auf der PlatteTatsächlich belegte Blöcke, Verzeichnisblöcke inbegriffendu -s --block-size=1
KapazitätFreier Platz von gesamt, auf dem gescannten Dateisystemder Avail-Spalte von df, exakt

Sie weichen in beide Richtungen ab, und beide sind richtig. Eine Ein-Byte-Datei belegt einen ganzen Block, ist auf der Platte also größer als ihre Länge. Eine Sparse-Datei gibt eine Länge an, die sie nie belegt hat: ein Platten-Image kann ein Terabyte behaupten und neunzehn Gigabyte belegen.

Sparse-Dateien sind der Grund, warum die App auf der Platte voreinstellt. Images virtueller Maschinen, Datenbankdateien und Core-Dumps gehören auf jeder echten Platte zu den größten Einträgen — das logische Maß irrt sich also genau bei den Einträgen am stärksten, die am meisten zählen. Die Kommandozeile stellt logisch voreingestellt, und beide sagen, welches sie zeigen.

Die Kapazität wird als frei von gesamt gemeldet, nie als „% belegt“. Auf einem Dateisystem, dessen Platz zwischen Volumes geteilt wird — APFS-Container, btrfs-Subvolumes, Thin-LVM — würde eine Belegt-Zahl die Geschwister mitzählen und df für denselben Mountpunkt widersprechen.

Hardlinks werden standardmäßig einmal gezählt; die zweite Kopie erscheint im Baum mit einem Beitrag von null Byte. Symlinks werden nie verfolgt und zählen mit ihrer eigenen Größe.

Befehlsübersicht

spacetrace scan PATH
--save, --label
spacetrace scans
spacetrace diff
--path, --since-last, ID ID
spacetrace ls PATH
--top, --scan, --subpath
spacetrace export
--scan, --out
spacetrace pull --root PATH
--remote
spacetrace prune / rm
--keep, ID
spacetrace-agent init
spacetrace-agent check
spacetrace-agent serve
spacetrace-agent push URL
--root, --token

Optionen, die bei den meisten Befehlen gelten

  • --exclude NAME
  • -x, --one-file-system
  • --depth N
  • --min SIZE
  • --files
  • --no-dedupe
  • --json
  • --db PATH
  • --remote NAME|URL

Wo was liegt

PlattformMomentaufnahmen-Datenbank
macOS~/Library/Application Support/spacetrace/
Linux$XDG_DATA_HOME/spacetrace/
ÜberallSPACETRACE_HOME überschreibt das; --db überschreibt es für einen einzelnen Befehl

Die Desktop-App schreibt in dieselbe Datenbank: eine in der App gespeicherte Momentaufnahme erscheint in spacetrace scans — und umgekehrt.

Bekannte Grenzen

Veröffentlicht, statt entdeckt zu werden. Wenn Sie auf eine davon stoßen, ist es bekannte Schuld, keine Überraschung.

  • Unter Windows entspricht die Größe auf der Platte der logischen Größe, und die Hardlink-Deduplizierung ist aus. Echte Zahlen brauchen GetFileInformationByHandleEx und FileIdInfo.
  • APFS-Klone werden nicht dedupliziert, und auf btrfs oder ZFS führen Reflinks und Kompression dazu, dass ein Baumdurchlauf die echte Nutzung nicht melden kann. Kein Baumdurchlauf kann das; die Zahlen sind die der Dateien selbst.
  • Ein Scan hält den ganzen Baum im Speicher. Das Speicherprofil jenseits von zehn Millionen Dateien ist nicht gemessen.
  • Der Agent hat kein TLS und keine Ratenbegrenzung. Nutzen Sie einen Reverse Proxy; das Token ist ohnehin Pflicht.
  • Der Scheduler hat keine Zeitzonendatenbank — UTC plus ein fester Offset, Sommerzeitwechsel bleiben also Ihre Sache.

docs/AGENT.md