Jak mogę monitorować użycie procesora przez użytkownika?

15

Muszę monitorować użycie procesora przez użytkowników dwóch serwerów (Ubuntu i CentOS). Na przykład:

user1     5%
user2    10%
...

Czy istnieje narzędzie podobne do toplub htopże można to zrobić?

Amged Rustom
źródło
Czy potrzebujesz góry, aby wyświetlać się w czasie rzeczywistym? W przeciwnym razie możesz rozważyć wynik top -u useri przekierować go do pliku, a następnie monitorować innego użytkownika. będziesz mieć monitor użycia proc dla użytkowników w danym przedziale czasowym.
Laurent C.
Kiedy mówisz monitor w jakim okresie? Raz na jakiś czas czy ciągle?
slm
Mam nadzieję, że będę w stanie monitorować użytkowników w czasie rzeczywistym, jak top.
Amged Rustom

Odpowiedzi:

17

Oto skrypt do wydrukowania całkowitego zużycia procesora dla każdego aktualnie zalogowanego użytkownika , 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; }'

A oto nieco zmodyfikowana wersja do drukowania wykorzystania procesora przez wszystkich dostępnych użytkowników (ale pomijająca tych z zerowym użyciem procesora), 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; }'

Pierwsza kolumna reprezentuje nazwę użytkownika, druga kolumna zagregowane użycie procesora, a trzecia kolumna znormalizowane użycie procesora zgodnie z liczbą rdzeni procesora.

Istnieje również powiązany skrypt pokazujący całkowite użycie pamięci dla każdego użytkownika: showPerUserMem.sh

Aby monitorować na żywo, wykonuj te skrypty okresowo za pomocą watch polecenia.

Aby posortować według użycia procesora, potokuj wyjście do sort -k2 -nr.

scai
źródło
1
dlaczego mieszacie zmienną bash env ze zmienną skryptową, oznacza to, że $ USER już istnieje, nawet wszystkie zmienne wielkich liter są env, prawda?
Rahul Patil
Nie sądzę, że wszystkie zmienne pisane wielkimi literami muszą być zmiennymi środowiskowymi. Ale zgadzam się, że zastąpienie już istniejących zmiennych nie jest zbyt ładnym stylem.
scai
1
Generalnie źle jest używać UPPERCASE w bash, z tego powodu, o którym wspomniał Rahul. Jest jeszcze gorzej, gdy używasz nazwy zmiennej, która już istnieje jako środowiskowa (n bash, $USERto już twoja nazwa użytkownika, więc ut jest taka sama jak id -nukomenda, której używasz. Edytowałem twój post, aby to zmienić.
terdon
Używanie zmiennych pisanych wielkimi literami w skryptach powłoki z pewnością nie jest złym pomysłem, ponieważ /etc/init.d/robi to również dziewięć na dziesięć skryptów w moim katalogu. Należy natomiast unikać nadpisywania istniejących zmiennych środowiskowych.
scai
1
Dodałem wersję uwzględniającą każdego użytkownika, nie tylko aktualnie zalogowanego.
Scai