Qual è il modo più giusto per monitorare il tempo totale della CPU - per utente?


25

Su un sistema multiutente, voglio misurare l'utilizzo della CPU di ogni utente in pochi secondi di tempo della CPU. Ai fini di questa misurazione, suppongo che se un PID appartiene a un utente, questo utente sta causando il tempo della CPU, ovvero sto ignorando i daemon e il kernel.

Attualmente lo sto facendo, ogni cinque secondi:

  1. Ottieni ogni utente e i PID che stanno eseguendo ps aux
  2. Per ogni PID, ottenere x, la somma di utime, cutime, stime e cstime da/proc/[pid]/stat
  3. calcola t = x / interval(l'intervallo non è sempre esattamente 5 secondi quando c'è un carico elevato)

Se eseguo questo, ottengo valori dall'aspetto sensato. Ad esempio: un utente di questo sistema ruotava in python ( while True: pass) e il sistema mostrava circa 750 millisecondi di tempo di CPU al secondo. Quando il sistema si è bloccato per un po ', ha riportato 1600ms per un inverter da 1 secondo. Il che sembra giusto, ma capisco che questi valori possono essere ingannevoli, soprattutto se non li capisco davvero .

Quindi la mia domanda è questa:

Qual è un modo giusto e corretto per misurare il carico della CPU in base all'utente?

Il metodo deve essere piuttosto accurato. Potrebbero esserci molte centinaia di utenti su questo sistema, quindi l'estrazione delle percentuali ps auxnon sarà abbastanza accurata, specialmente per i thread di breve durata che molti software vogliono generare.

Anche se questo potrebbe essere complicato, so assolutamente che è possibile. Questo è stato il mio punto di partenza:

Il kernel tiene traccia del tempo di creazione di un processo e del tempo della CPU che consuma durante la sua vita. Ad ogni tick, il kernel aggiorna la quantità di tempo in jiffies che il processo corrente ha trascorso nel sistema e in modalità utente. - (dal Linux Documentation Project )

Il valore che sto cercando è la quantità di secondi (o jiffies) che un utente ha speso per la CPU, non una percentuale di carico del sistema o utilizzo della CPU.

È importante misurare il tempo della CPU mentre i processi sono ancora in esecuzione. Alcuni processi dureranno solo mezzo secondo, alcuni dureranno molti mesi - e dobbiamo prendere entrambi i tipi, in modo da poter tenere conto del tempo di CPU degli utenti con granularità.


1
500 reputazione: o buone possibilità per i principianti
Tachioni

Un po 'fuori dalla mia portata, ma una domanda molto interessante così ho scavato un po' e ho trovato qualcosa che mi auguro è almeno utile per aiutare a risolvere questo: stackoverflow.com/a/1424556/905573
kingmilo

1
sai toppuoi fare la modalità batch? top -b -n 1 -u {user} | awk 'NR>7 { sum += $9; } END { print sum; }'dovrebbe mostrare il carico per {utente} in quel momento.
Rinzwind

Risposte:


11

Sembra che tu abbia bisogno della contabilità di processo.

http://www.faqs.org/docs/Linux-mini/Process-Accounting.html

Su Ubuntu, gli strumenti di contabilità di processo sono nel acctpacchetto Installa acct

Per ottenere un rapporto per utente, esegui

sa -m

Sfortunatamente, questo non funzionerà per me poiché "sa" non conterà i processi di lunga durata. Ciò di cui ho bisogno (penso) è un modo per rilevare i processi avviati e terminati e per registrare il loro tempo della CPU quando si chiudono, così come mentre sono in esecuzione.
Stefano Palazzo

@StefanoPalazzo Credo che questo sia il migliore che otterrai. Aumentalo con i tempi per l'esecuzione dei processi da /proc/[pid]/stat.
ændrük,

A quanto pare, sembra che la maggior parte di tutti i processi saranno considerati correttamente da sa(.ps.gz) . E ho anche un buon modo per "stimare" quei processi di lunga durata, prima di ottenere un valore preciso anche per quelli. Quindi lo useremo dopo tutto, e sono più che felice di assegnare la generosità alla tua risposta. Grazie mille!
Stefano Palazzo

3

Questo fornirà una linea per ogni utente che mostra il nome utente e il loro tempo totale della CPU:

ps -w -e --no-header -o uid,user \
        | sort -u \
        | while read uid user; do
                echo -e "$user\t"$(
                        ps --no-headers -u $uid --cumulative -o time \
                                | sed -e s/:/*3600+/ -e s/:/*60+/ \
                                | paste -sd+ \
                                | bc
                );
        done

2

Una delle risposte più ovvie è quella di estendere ciò che stai facendo ora.

Mi sono imbattuto in questo processo di monitoraggio per l'utilizzo di script bash e mysql per tenere traccia del tempo della CPU degli utenti, ma è stato suddiviso in un intervallo di tempo molto più ampio di quello di cui stavi parlando.

Spero che questo possa darti qualche idea in più sulla direzione in cui stai cercando di andare.

http://www.dba-oracle.com/t_oracle_unix_linux_vmstat_capture.htm


0

Questo gestirà anche i processi che sono in esecuzione da giorni..non sono sicuro di come espandere per settimane / mesi / anni ..

ps -w -e --no-header -o uid,user \
    | sort -u \
    | while read uid user; do
            echo -e "$user\t"$(
                    ps --no-headers -u $uid --cumulative -o time \
                          | sed -e s/-/*86400+/ -e s/:/*3600+/ -e s/:/*60+/ 
                          | paste -sd+ \
                          | bc
            );
    done
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.