Wie kann ich die CPU-Auslastung nach Benutzer überwachen?

15

Ich muss die CPU-Auslastung von Benutzern von zwei Servern (Ubuntu und CentOS) überwachen. Beispielsweise:

user1     5%
user2    10%
...

Gibt es ein ähnliches Tool topoder htopdas kann das?

Amged Rustom
quelle
Benötigen Sie ein Top, um in Echtzeit angezeigt zu werden? Andernfalls können Sie top -u userdas Ergebnis prüfen und in eine Datei umleiten und dann einen anderen Benutzer überwachen. In einem bestimmten Intervall haben Sie dann eine Überwachung der Proc-Nutzung für Ihre Benutzer.
Laurent C.
Wann sagen Sie Monitor über welchen Zeitraum? Hin und wieder oder ununterbrochen?
SLM
Ich hoffe in der Lage zu sein, Benutzer in Echtzeit wie oben zu überwachen.
Amged Rustom

Antworten:

17

Hier ist ein Skript zum Drucken der gesamten CPU-Auslastung für jeden derzeit angemeldeten Benutzer , showPerUserCPU.sh :

own=$(id -nu)
cpus=$(lscpu | grep "^CPU(s):" | awk '{print $2}')

for user in $(who | awk '{print $1}' | sort -u)
do
    # print other user's CPU usage in parallel but skip own one because
    # spawning many processes will increase our CPU usage significantly
    if [ "$user" = "$own" ]; then continue; fi
    (top -b -n 1 -u "$user" | awk -v user=$user -v CPUS=$cpus 'NR>7 { sum += $9; } END { print user, sum, sum/CPUS; }') &
    # don't spawn too many processes in parallel
    sleep 0.05
done
wait

# print own CPU usage after all spawned processes completed
top -b -n 1 -u "$own" | awk -v user=$own -v CPUS=$cpus 'NR>7 { sum += $9; } END { print user, sum, sum/CPUS; }'

Und hier ist eine leicht modifizierte Version zum Drucken der CPU-Auslastung aller verfügbaren Benutzer (wobei diejenigen mit einer CPU-Auslastung von Null übersprungen werden): showAllPerUserCPU.sh :

own=$(id -nu)
cpus=$(lscpu | grep "^CPU(s):" | awk '{print $2}')

for user in $(getent passwd | awk -F ":" '{print $1}' | sort -u)
do
    # print other user's CPU usage in parallel but skip own one because
    # spawning many processes will increase our CPU usage significantly
    if [ "$user" = "$own" ]; then continue; fi
    (top -b -n 1 -u "$user" | awk -v user=$user -v CPUS=$cpus 'NR>7 { sum += $9; } END { if (sum > 0.0) print user, sum, sum/CPUS; }') &
    # don't spawn too many processes in parallel
    sleep 0.05
done
wait

# print own CPU usage after all spawned processes completed
top -b -n 1 -u "$own" | awk -v user=$own -v CPUS=$cpus 'NR>7 { sum += $9; } END { print user, sum, sum/CPUS; }'

Die erste Spalte repräsentiert den Benutzernamen, die zweite Spalte die aggregierte CPU-Auslastung und die dritte Spalte die normalisierte CPU-Auslastung entsprechend der Anzahl der CPU-Kerne.

Es gibt auch ein zugehöriges Skript zum Anzeigen der Gesamtspeicherbelegung für jeden Benutzer: showPerUserMem.sh

Für die Live-Überwachung führen Sie diese Skripte einfach regelmäßig über den watchBefehl aus.

Um nach CPU-Auslastung zu sortieren, leiten Sie die Ausgabe an sort -k2 -nr.

scai
quelle
1
Warum mischen Sie die Bash-Env-Variable mit der Skript-Variable? Das bedeutet, dass $ USER bereits existiert.
Rahul Patil
Ich glaube nicht, dass alle Variablen in Großbuchstaben Umgebungsvariablen sein müssen. Ich stimme jedoch zu, dass das Überschreiben bereits vorhandener Variablen kein sehr schöner Stil ist.
Scai
1
Es ist im Allgemeinen eine schlechte Idee, UPPERCASE in bash zu verwenden, aus dem Grund, den Rahul erwähnte. Es ist noch schlimmer, wenn Sie einen Variablennamen verwenden, der bereits als Umgebungsname existiert (n bash, $USERist Ihr Benutzername bereits, also ist er derselbe wie der id -nuBefehl, den Sie verwenden. Ich habe Ihren Beitrag bearbeitet, um dies zu ändern.
terdon
Die Verwendung von Variablen in Großbuchstaben in Shell-Skripten ist sicherlich keine schlechte Idee, da dies auch neun von zehn Skripten in meinem /etc/init.d/Verzeichnis tun. Das Überschreiben vorhandener Umgebungsvariablen sollte dagegen vermieden werden.
Scai
1
Ich habe eine Version hinzugefügt, um alle Benutzer
einzuschließen