spacetrace
IT
Scarica

Guida

Tutto ciò che fa lo strumento a riga di comando, nell'ordine in cui probabilmente ti servirà. --help su qualsiasi comando stampa la stessa cosa senza browser.

Prima scansione

Una scansione percorre una cartella e stampa ciò che ha trovato. Niente viene salvato, niente viene modificato.

$ 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

I percorsi illeggibili vengono contati e campionati invece di fermare il percorso. Su macOS, andare fuori dalla cartella home richiede il Full Disk Access per il terminale; senza, la scansione si completa comunque e ti dice cosa ha mancato.

Renderla più veloce e più ristretta

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

--exclude prende il nome di una directory, non un percorso, e si ripete. Nelle cartelle escluse non si scende mai: escludere node_modules su una macchina da sviluppo è di solito la differenza fra due secondi e trenta.

Istantanee e confronto

Questa è la parte che gli altri analizzatori non hanno. Salva una scansione, salvane un'altra più tardi e chiedi cosa è cambiato.

$ 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

Poi confronta. Senza argomenti prende le ultime due.

$ 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/
Perché nomina la cartella più profonda

Una cartella la cui crescita viene interamente da un solo figlio non ti dice nulla di nuovo, quindi viene saltata. Il report nomina il primo livello in cui la variazione si distribuisce davvero — il colpevole, non i suoi antenati.

Contro il disco così com'è ora

Non ti servono due istantanee. Confronta la più recente con una scansione dal vivo:

spacetrace diff --since-last /srv

Scegliere cosa compare

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

Evitare che il database cresca all'infinito

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

Esplorare una scansione

ls elenca le cartelle per dimensione, da una scansione dal vivo o da un'istantanea salvata.

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

Per passare un'istantanea a qualcos'altro, export scrive il formato di ncdu:

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

Ogni comando accetta anche --json, che è il modo supportato per scriptarci sopra. Le colonne leggibili possono cambiare; la forma del JSON no.

L'agente su un server

spacetrace-agent è lo stesso codice come servizio: scansiona su pianificazione le radici che configuri, conserva le istantanee e risponde via HTTP. È un binario statico, e legge soltanto — al suo interno non esiste alcun percorso di codice che cancelli qualcosa fuori dal proprio database di istantanee.

  1. Scrivi una configurazione e un token

    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 rifiuta di partire senza un token. Un agente senza autenticazione consegna l'intero inventario del filesystem a chiunque riesca a raggiungere la porta.

  2. Di' cosa scansionare e quando

    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

    Cinque campi cron, con *, a-b, */n ed elenchi. Nessun secondo, nessun @daily. Le chiavi di configurazione sconosciute vengono rifiutate all'avvio, perché un errore di battitura che non fa nulla in silenzio su una macchina che nessuno guarda è peggio di un rifiuto di avviarsi.

  3. Controlla prima di avviarlo

    $ 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.

    Una pianificazione che non può mai scattare riporta never invece di fallire in silenzio.

  4. Avvialo

    systemctl enable --now spacetrace-agent

    L'unità systemd inclusa esegue l'agente come utente non privilegiato con ProtectSystem=strict, a Nice=10 e con priorità I/O idle. Una scansione non deve mai mettersi fra la macchina e ciò per cui esiste.

    In Docker, monta l'host in sola lettura e scansiona quello:

    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

Prima di esporlo

  • Ascolta su loopback per impostazione predefinita. Pubblicare l'inventario di un filesystem su una rete deve essere una scelta deliberata.
  • Nell'agente non c'è TLS. Mettici davanti un reverse proxy.
  • Il token è confrontato senza uscita anticipata, quindi un token sbagliato richiede lo stesso tempo per essere rifiutato, per quanto ne fosse corretto.
  • /health non richiede token, così un healthcheck del container funziona, e restituisce solo stato e versione — nessun hostname, nessuna radice.
  • Le scansioni su richiesta sono disattivate. Con quelle attive, chi ha il token può elencare qualsiasi directory leggibile dall'utente dell'agente.

Leggere un'altra macchina

Qualsiasi comando di sola lettura accetta --remote. Non c'è nulla di nuovo da imparare: gli stessi sottocomandi, puntati altrove.

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

Salva un remoto così URL e token smettono di essere digitati — in ~/.config/spacetrace/remotes.toml:

[remotes.nas]
url = "https://nas.example.com"
token = "…"
Un'istantanea remota non è una cosa diversa

Ciò che arriva dalla rete è lo stesso file SQLite autonomo che l'agente conserva: elencarla, esplorarla e confrontarla esegue lo stesso codice di un'istantanea locale. Puoi anche saltare lo strumento e ottenere comunque un file apribile:

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

scan, prune e rm rifiutano di girare con --remote: agiscono sullo stato locale, e l'agente non cancella nulla.

Quale dimensione, e perché

Ogni voce porta due numeri, e nessuno dei due è una stima dell'altro.

MisuraChe cos'èCoincide con
logicaLa lunghezza dichiarata da ogni filedu -sb
su discoBlocchi effettivamente allocati, inclusi quelli delle directorydu -s --block-size=1
capacitàSpazio libero sul totale, nel filesystem scansionatola colonna Avail di df, esattamente

Divergono in entrambe le direzioni ed entrambe sono corrette. Un file di un byte alloca un blocco intero, quindi su disco è più grande della sua lunghezza. Un file sparso dichiara una lunghezza che non ha mai allocato: un'immagine disco può dichiarare un terabyte e occuparne diciannove gigabyte.

I file sparsi sono il motivo per cui l'app usa su disco per impostazione predefinita. Immagini di macchine virtuali, file di database e core dump sono fra le voci più grandi su qualsiasi disco reale: la misura logica sbaglia di più proprio sulle voci che contano di più. La riga di comando usa logica come predefinita, ed entrambe dicono quale stanno mostrando.

La capacità è riportata come libero sul totale, mai come “% usato”. Su un filesystem il cui spazio è condiviso fra volumi — un container APFS, subvolumi btrfs, LVM thin — una cifra di spazio usato includerebbe i fratelli e contraddirebbe df sullo stesso mount.

Gli hardlink sono contati una sola volta per impostazione predefinita; la seconda copia appare nell'albero con un contributo di zero byte. I symlink non sono mai seguiti e contano per la propria dimensione.

Riferimento dei comandi

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

Opzioni che funzionano su quasi tutti i comandi

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

Dove vengono conservate le cose

PiattaformaDatabase delle istantanee
macOS~/Library/Application Support/spacetrace/
Linux$XDG_DATA_HOME/spacetrace/
OvunqueSPACETRACE_HOME lo sovrascrive; --db lo sovrascrive per un singolo comando

L'app desktop scrive nello stesso database, quindi un'istantanea salvata nell'app appare in spacetrace scans e viceversa.

Limiti noti

Pubblicati invece di essere scoperti. Se ne incontri uno è debito noto, non una sorpresa.

  • Su Windows la dimensione su disco è pari a quella logica e la deduplicazione degli hardlink è disattivata. Le cifre reali richiedono GetFileInformationByHandleEx e FileIdInfo.
  • I cloni APFS non sono deduplicati, e su btrfs o ZFS reflink e compressione fanno sì che un attraversamento dell'albero non possa riportare l'uso reale. Nessun tree walker può; i numeri sono quelli dei file.
  • Una scansione tiene l'intero albero in memoria. Il profilo di memoria oltre i dieci milioni di file non è stato misurato.
  • L'agente non ha TLS né rate limiting. Usa un reverse proxy; il token è già obbligatorio.
  • Lo scheduler non ha un database dei fusi orari — UTC più un offset fisso, quindi i cambi dell'ora legale restano da gestire a te.

docs/AGENT.md