Qual é a maneira mais justa de monitorar o tempo total de CPU - por usuário?

25

Em um sistema multiusuário, desejo medir o uso da CPU de cada usuário em segundos de tempo da CPU. Para os fins desta medição, presumo que, se um PID pertence a um usuário, ele está causando o tempo de CPU - ou seja, estou ignorando os daemons e o kernel.

Atualmente, estou fazendo isso a cada cinco segundos:

  1. Obtenha cada usuário e os PIDs que estão executando por meio de ps aux
  2. Para cada PID, obtenha xa soma de utime, cutime, stime e cstime de/proc/[pid]/stat
  3. calcular t = x / interval(o intervalo nem sempre é exatamente 5 segundos quando há carga alta)

Se eu executar isso, obtenho valores de aparência sensatos. Por exemplo: Um usuário neste sistema estava girando em python ( while True: pass) e o sistema mostrava cerca de 750 milissegundos de tempo de CPU por segundo. Quando o sistema travou um pouco, ele relatou 1600ms por um inverval de 1 segundo. O que parece certo, mas eu entendo que esses valores podem ser enganosos, especialmente porque eu realmente não os entendo.

Então, minha pergunta é esta:

Qual é uma maneira justa e correta de medir a carga da CPU por usuário?

O método deve ser bastante preciso. Pode haver muitas centenas de usuários nesse sistema, portanto, a extração de porcentagens ps auxnão será precisa o suficiente, especialmente para threads de vida curta, dos quais muitos softwares gostam de gerar.

Embora isso possa ser complicado, eu absolutamente sei que é possível. Este foi o meu ponto de partida:

O kernel controla o tempo de criação de processos, bem como o tempo de CPU que consome durante sua vida útil. A cada tique do relógio, o kernel atualiza a quantidade de tempo em instantes que o processo atual passou no sistema e no modo de usuário. - (do projeto de documentação do Linux )

O valor que busco é a quantidade de segundos (ou instantes) que um usuário gasta na CPU, não uma porcentagem da carga do sistema ou uso da CPU.

É importante medir o tempo da CPU enquanto os processos ainda estão em execução. Alguns processos duram apenas meio segundo, outros duram muitos meses - e precisamos capturar os dois tipos, para podermos contabilizar o tempo de CPU dos usuários com granularidade fina.

Stefano Palazzo
fonte
1
500 reputação: o boa chance para iniciantes
Tachyons
Um pouco fora do meu alcance, mas uma questão muito interessante, então eu cavei um pouco e encontrei algo que eu espero é, pelo menos, útil para ajudar a resolver este: stackoverflow.com/a/1424556/905573
kingmilo
1
você sabe que toppode fazer o modo em lote? top -b -n 1 -u {user} | awk 'NR>7 { sum += $9; } END { print sum; }'deve mostrar a carga para {usuário} naquele momento.
Rinzwind

Respostas:

11

Parece que você precisa da contabilidade do processo.

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

No Ubuntu, as ferramentas de contabilidade de processo estão no acctpacote Instalar conta

Para obter um relatório por usuário, execute

sa -m
Alan Bell
fonte
Infelizmente, isso não funcionará para mim, pois "sa" não contará com processos de execução longa. O que eu preciso (acho) é uma maneira de detectar os processos iniciados e finalizados e registrar o tempo da CPU quando eles saem, bem como enquanto estão em execução.
Stefano Palazzo
@StefanoPalazzo Eu acredito que este é o melhor que você terá. Aumente-o com tempos para a execução de processos a partir de /proc/[pid]/stat.
ændrük
Como se vê, parece que quase todos os processos serão contabilizados adequadamente por sa(.ps.gz) . E também tenho uma boa maneira de "estimar" esses processos de longa execução, antes de, eventualmente, obter um valor preciso para eles também. Afinal, vamos usá-lo, e estou mais do que feliz em atribuir a recompensa à sua resposta. Muito obrigado!
Stefano Palazzo
3

Isso fornecerá uma linha para cada usuário, mostrando o nome de usuário e o tempo total da 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
Marques Johansson
fonte
2

Uma das respostas mais óbvias é apenas estender o que você está fazendo atualmente.

Me deparei com esse processo de monitor usando o bash scripting e o mysql para rastrear o tempo da CPU dos usuários, mas ele se estendeu por um período muito maior do que você estava falando.

Espero que isso possa lhe dar mais algumas idéias sobre a direção que você está procurando seguir.

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

Linztm
fonte
0

Isso também tratará dos processos que estão em execução há dias .. não sei como expandir por semanas / meses / anos.

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
Patrik Arlos
fonte