¿Cuál es la forma más justa de monitorear el tiempo total de CPU por usuario?

25

En un sistema multiusuario, quiero medir el uso de CPU de cada usuario en segundos de tiempo de CPU. Para el propósito de esta medición, supongo que si un PID pertenece a un usuario, este usuario está causando el tiempo de CPU, es decir, estoy ignorando los demonios y el núcleo.

Actualmente estoy haciendo esto, cada cinco segundos:

  1. Obtenga cada usuario y los PID que están ejecutando a través de ps aux
  2. Para cada PID, obtenga xla suma de tiempo, tiempo de corte, tiempo y cstime de/proc/[pid]/stat
  3. calcular t = x / interval(el intervalo no siempre es exactamente 5 segundos cuando hay mucha carga)

Si ejecuto esto, obtengo valores razonables. Por ejemplo: un usuario en este sistema estaba girando en python ( while True: pass), y el sistema mostraba alrededor de 750 milisegundos de tiempo de CPU por segundo. Cuando el sistema se colgó por un momento, reportó 1600 ms para un inverval de 1 segundo. Lo que parece correcto, pero entiendo que estos valores pueden ser engañosos, especialmente dado que realmente no los entiendo.

Así que mi pregunta es esta:

¿Cuál es una forma justa y correcta de medir la carga de la CPU por usuario?

El método tiene que ser bastante preciso. Puede haber muchos cientos de usuarios en este sistema, por lo que extraer porcentajes ps auxno será lo suficientemente preciso, especialmente para los hilos de corta duración que muchas piezas de software les gusta generar.

Si bien esto puede ser complicado, sé absolutamente que es posible. Este fue mi punto de partida:

El núcleo realiza un seguimiento del tiempo de creación de procesos y del tiempo de CPU que consume durante su vida útil. Cada vez que se marca el reloj, el kernel actualiza la cantidad de tiempo en segundos que el proceso actual ha pasado en el sistema y en el modo de usuario. - (del Proyecto de documentación de Linux )

El valor que busco es la cantidad de segundos (o segundos) que un usuario ha gastado en la CPU, no un porcentaje de la carga del sistema o el uso de la CPU.

Es importante medir el tiempo de CPU mientras los procesos aún se están ejecutando. Algunos procesos solo durarán medio segundo, algunos durarán muchos meses, y necesitamos capturar ambos tipos, para que podamos dar cuenta del tiempo de CPU de los usuarios con granularidad fina.

Stefano Palazzo
fuente
1
500 reputación: o buena oportunidad para principiantes
Tachyons
Un poco fuera de mi alcance, pero una pregunta muy interesante, así que busqué un poco y encontré algo que espero sea al menos útil para ayudarlo a resolver esto: stackoverflow.com/a/1424556/905573
kingmilo
1
sabes que toppuede hacer el modo por lotes? top -b -n 1 -u {user} | awk 'NR>7 { sum += $9; } END { print sum; }'debería mostrar la carga para {usuario} en ese momento.
Rinzwind

Respuestas:

11

Parece que necesita contabilidad de procesos.

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

En Ubuntu, las herramientas de contabilidad de procesos están en el acctpaquete Instalar acct

Para obtener un informe por usuario, ejecute

sa -m
Alan Bell
fuente
Desafortunadamente, esto no funcionará para mí ya que "sa" no contará los procesos de larga duración. Lo que necesito (creo) es una forma de detectar procesos que se inician y finalizan, y registrar su tiempo de CPU cuando se cierran, así como mientras se están ejecutando.
Stefano Palazzo
@StefanoPalazzo Creo que esto es lo mejor que obtendrás. Aumentarlo con tiempos para ejecutar procesos desde /proc/[pid]/stat.
ændrük
Como resultado, parece que la mayoría de los procesos serán contabilizados adecuadamente por sa(.ps.gz) . Y también tengo una buena manera de "estimar" esos procesos de larga ejecución, antes de obtener un valor preciso para ellos. Así que lo usaremos después de todo, y estoy más que feliz de otorgarle la recompensa por su respuesta. ¡Gracias un montón!
Stefano Palazzo
3

Esto dará una línea para cada usuario que muestra el nombre de usuario y su tiempo total de 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
fuente
2

Una de las respuestas más obvias es simplemente extender lo que estás haciendo actualmente.

Encontré este proceso de monitor para usar bash scripting y mysql para rastrear el tiempo de CPU de los usuarios, pero se extendió a través de un marco de tiempo mucho mayor de lo que estaba hablando.

Espero que esto pueda darle algunas ideas más sobre la dirección en la que está buscando dirigirse.

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

Linztm
fuente
0

Esto también manejará los procesos que se han estado ejecutando durante días ... no estoy seguro de cómo expandirse durante semanas / meses / años ...

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
fuente