Linux: comando “bpftrace” per il tracing dinamico di kernel e applicazioni

INFORMATICA, LINUX, TUTORIAL

Introduzione a ‘bpftrace’ e alle tecnologie eBPF

Nell’era moderna, la gestione delle prestazioni e la diagnosi dei problemi di sistema sono cruciali per amministratori di sistema e sviluppatori. Tecnologie come eBPF (extended Berkeley Packet Filter) emergono come potenti strumenti per l’osservabilità dinamica. Tra le varie applicazioni e strumenti basati su eBPF, ‘bpftrace’ si distingue per il suo intuitivo e potente tracciamento di kernel e applicazioni.

eBPF, originariamente introdotto per il filtraggio dei pacchetti di rete, è oggi utilizzato in molteplici contesti grazie alla sua versatilità. Consente di eseguire bytecode sicuro direttamente nel kernel Linux, offrendo un potente strumento di monitoraggio e tracciamento delle attività del sistema operativo a livello di kernel con un overhead minimo. eBPF può collegarsi a vari punti del kernel, raccogliendo dati e fornendo una visione dettagliata del comportamento del sistema.

‘bpftrace’ è uno strumento basato su eBPF che permette di eseguire script per tracciare e monitorare attività specifiche nel kernel e nelle applicazioni. Ispirato alla sintassi di DTrace e AWK, rende la scrittura di script accessibile a chi ha familiarità con questi strumenti, permettendo di agire granularmente su syscall, eventi di scheduling, funzioni kernel e applicazioni, offrendo una visibilità senza precedenti sui sistemi Linux.

Un esempio classico di script bpftrace è il seguente:

#!/usr/bin/env bpftrace
interval:s:1 {
    printf("Procs running: %d\n", nprocs());
}

Questo script stampa il numero di processi in esecuzione ogni secondo. La sintassi di bpftrace permette di scrivere script complessi in modo conciso ed efficace, sfruttando la potenza dei dati raccolti direttamente dal kernel.

Un altro esempio utile riguarda il monitoraggio delle chiamate di funzione. Lo script seguente traccia ogni invocazione della funzione di lettura di file e cattura il nome del file:

tracepoint:syscalls:sys_enter_read {
    printf("Reading file descriptor: %d\n", args->fd);
}

Con questo script, è possibile ottenere dettagli precisi sul comportamento del sistema, cruciali per diagnosticare problemi di prestazioni o bug.

Installazione e configurazione di ‘bpftrace’

bpftrace è uno strumento basato su eBPF che semplifica il tracing dinamico di kernel e applicazioni su sistemi Linux. Per iniziare a utilizzare bpftrace, è necessario eseguire una serie di passaggi per la sua installazione e configurazione.

Installazione di bpftrace

Prima di tutto, assicurarsi di avere un kernel Linux compatibile. bpftrace richiede un kernel recente, solitamente una versione successiva alla 4.9. È anche necessario avere installate le librerie di sviluppo delle intestazioni del kernel.

Per utenti di distribuzioni popolari come Ubuntu o Debian, bpftrace può essere installato direttamente dai repository ufficiali:

sudo apt-get update
sudo apt-get install bpftrace

Per distribuzioni basate su Red Hat, come Fedora o CentOS, il comando di installazione è il seguente:

sudo dnf install bpftrace (Fedora)
sudo yum install bpftrace (CentOS)

Nel caso in cui il pacchetto non sia disponibile nei repository, è possibile compilare bpftrace dai sorgenti. Prima di tutto, assicurarsi di avere gli strumenti di compilazione necessari:

sudo apt-get install bison cmake flex git libelf-dev clang

Quindi, clonare il repository di bpftrace e compilarlo:

git clone https://github.com/iovisor/bpftrace.git
cd bpftrace
mkdir build
cd build
cmake ..
make
sudo make install

Configurazione iniziale

Dopo aver installato bpftrace, è importante configurarlo correttamente per garantirne il funzionamento ottimale. Una delle prime verifiche da effettuare è l’abilitazione dei flag di debug del kernel, necessari per il corretto funzionamento di bpftrace:

sudo sysctl -w kernel.yama.ptrace_scope=1

Assicurarsi che bpftrace sia configurato per accedere ai punti di hook necessari. Questo può essere fatto verificando il montaggio del filesystem di debug:

sudo mount -t debugfs none /sys/kernel/debug

È utile verificare che l’utente disponga dei permessi per accedere alle informazioni di debug del kernel. Questo può essere realizzato aggiungendo l’utente al gruppo tracing:

sudo usermod -aG tracing $USER

Dopo la configurazione, un buon test iniziale è eseguire un semplice script di bpftrace. Creare un file di script con il seguente contenuto:

#!/usr/bin/env bpftrace
BEGIN { printf("Hello, bpftrace!\n"); }

Salvare il file come hello.bt, renderlo eseguibile e poi eseguirlo:

chmod +x hello.bt
./hello.bt

Se tutto è configurato correttamente, dovresti vedere il messaggio Hello, bpftrace! stampato nella console.

In sintesi, l’installazione e la configurazione di bpftrace non solo forniscono un potente strumento per il monitoraggio e il debugging dei sistemi Linux, ma anche la possibilità di esplorare e risolvere problemi di performance con precisione. Con una corretta configurazione, sviluppatori e amministratori di sistema possono trarre il massimo vantaggio dal monitoraggio dinamico basato su eBPF.

Monitorare il Sistema con bpftrace

Il comando bpftrace rappresenta uno strumento avanzato di tracing dinamico per sistemi Linux, costruito sopra l’infrastruttura eBPF (Extended Berkeley Packet Filter). Utilizzando bpftrace, gli amministratori di sistema possono ottenere dettagli sul funzionamento del kernel e delle applicazioni in esecuzione, con controllo granulare e precise funzionalità di osservazione.

Un aspetto fondamentale di bpftrace è la capacità di eseguire script semplici che permettono di monitorare vari aspetti del sistema in tempo reale. Gli script di bpftrace sono scritti in un linguaggio simile a C, rendendo la sintassi facilmente comprensibile per chiunque abbia esperienza di programmazione.

Per iniziare, creiamo un semplice script che traccia le chiamate di sistema. Ad esempio, per monitorare tutte le chiamate di sistema open(), possiamo scrivere il seguente script:

#!/usr/bin/env bpftrace
tracepoint:syscalls:sys_enter_open {
    printf("File open: %s\n", str(args->filename));
}

Questo script cattura ogni chiamata di sistema open e stampa il nome del file. Per eseguire lo script, salvarlo come file_open.bt, renderlo eseguibile e poi eseguirlo:

chmod +x file_open.bt
sudo ./file_open.bt

Ora, ogni volta che un’applicazione esegue una chiamata open, vedremo l’output sul terminale. Questo è un semplice esempio di come bpftrace può aiutare a osservare il comportamento di un sistema.

La potenza di bpftrace si manifesta quando si utilizzano script più complessi. Ad esempio, per monitorare la latenza delle chiamate di sistema read e write, lo script seguente potrebbe essere strutturato così:

#!/usr/bin/env bpftrace
tracepoint:syscalls:sys_enter_read {
    @start[tid] = nsecs;
}
tracepoint:syscalls:sys_exit_read {
    $start = @start[tid];
    @latency = hist(nsecs - $start);
    delete(@start[tid]);
}
interval:s:1 {
    print(@latency);
    clear(@latency);
}

Questo script memorizza il timestamp quando una chiamata read entra e calcola la latenza alla sua uscita, presentando un istogramma della latenza delle chiamate di sistema ogni secondo. Questa capacità di aggregare e visualizzare dati in tempo reale è cruciale per l’analisi delle performance e l’ottimizzazione dei sistemi.

Tracing avanzato delle performance delle applicazioni

bpftrace è uno strumento avanzato per il tracing dinamico su sistemi Linux, costruito sopra l’infrastruttura eBPF (Extended Berkeley Packet Filter). Utilizzando bpftrace, gli amministratori di sistema possono ottenere informazioni dettagliate sul funzionamento del kernel e delle applicazioni in esecuzione, con un controllo granulare e precise funzionalità di osservazione.

Una delle principali caratteristiche di bpftrace è la sua capacità di eseguire script personalizzati. Questi script, scritti in un linguaggio simile al C, permettono di monitorare in tempo reale vari eventi di sistema come chiamate di sistema, funzioni del kernel e altre attività. A differenza di altri strumenti di tracciamento, che possono richiedere conoscenze kernel avanzate, bpftrace facilita un accesso più semplice alle funzionalità di tracciamento avanzato.

Per illustrare le capacità di bpftrace, consideriamo il tracciamento delle chiamate di sistema. Un esempio pratico è il monitoraggio del tempo di esecuzione delle chiamate di sistema read. Con bpftrace, possiamo catturare l’evento di inizio e fine di una chiamata, misurando e aggregando il tempo impiegato:

#!/usr/bin/env bpftrace
tracepoint:syscalls:sys_enter_read {
    @start[tid] = nsecs;
}
tracepoint:syscalls:sys_exit_read
/ @start[tid] / {
    $start = @start[tid];
    @latency = hist(nsecs - $start);
    delete(@start[tid]);
}
interval:s:1 {
    print(@latency);
    clear(@latency);
}

Questo script memorizza il timestamp quando una chiamata read entra, calcola la latenza alla sua uscita e presenta un istogramma della latenza delle chiamate di sistema ogni secondo. Questa capacità di aggregare e visualizzare dati in tempo reale è cruciale per l’analisi delle performance e l’ottimizzazione dei sistemi.

bpftrace permette di monitorare eventi specifici del kernel, inclusi counter e funzioni definite dall’utente. Può integrarsi con altre utility di sistema e framework di monitoraggio, come perf e ftrace, permettendo una visione olistica delle performance del sistema.

l’uso di bpftrace richiede alcune precauzioni. Un monitoraggio prolungato e ad alta granularità potrebbe introdurre overhead sul sistema. È consigliato testare ogni script in ambienti di staging prima di implementarli in produzione, per evitare effetti collaterali imprevisti.

Se vuoi farmi qualche richiesta o contattarmi per un aiuto riempi il seguente form