Como posso monitorar o uso da CPU por usuário?


15

Preciso monitorar o uso da CPU por usuários de dois servidores (Ubuntu e CentOS). Por exemplo:

user1     5%
user2    10%
...

Existe uma ferramenta semelhante topou htopque possa fazer isso?


Você precisa que o top seja exibido em tempo real? Caso contrário, você pode considerar top -u usere redirecionar o resultado para um arquivo e monitorar outro usuário. você teria um monitor de uso de proc para seus usuários em um determinado intervalo.
— Laurent C.

Quando você diz monitorar durante que período? De vez em quando ou continuamente?
— Slm

Espero poder monitorar os usuários em tempo real, como top.
— Alterado Rustom

Respostas:


17

Aqui está um script para imprimir o uso total da CPU para cada usuário atualmente conectado , 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; }'

E aqui está uma versão ligeiramente modificada para imprimir o uso da CPU de todos os usuários disponíveis (mas ignorando aqueles com um uso zero da CPU), 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; }'

A primeira coluna representa o nome do usuário, a segunda coluna o uso agregado da CPU e a terceira coluna o uso normalizado da CPU de acordo com o número de núcleos da CPU.

Há também um script relacionado para mostrar o uso total de memória para cada usuário: showPerUserMem.sh

Para monitoramento ao vivo, execute esses scripts periodicamente através do watchcomando

Para classificar por uso da CPU, canalize a saída para sort -k2 -nr.


1
por que você está misturando a variável env do bash com a variável de script significa que $ USER já existe, mesmo que toda a variável caps seja env, não é?
— Rahul Patil

Eu não acho que todas as variáveis ​​maiúsculas devem ser variáveis ​​de ambiente. Mas concordo que a substituição de variáveis ​​já existentes não é um estilo muito agradável.
— Scai 20/03/2014

1
Geralmente, é uma má idéia usar o UPPERCASE no bash, pelo motivo que Rahul mencionou. É ainda pior quando você está usando um nome de variável que já existe como ambiental (n bash, $USERjá é seu nome de usuário, então ut é o mesmo que o id -nucomando que você está usando.
— Editei

Usar variáveis ​​maiúsculas em scripts shell certamente não é uma má idéia, pois nove em cada dez scripts no meu /etc/init.d/diretório também estão fazendo isso. A substituição de variáveis ​​de ambiente existentes em contraste deve ser evitada.
— Scal

1
Eu adicionei uma versão para incluir todos os usuários, não apenas os conectado no momento.
— Scal
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.