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?

Amged Rustom
fonte
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.

scai
fonte
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 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