Quelle est la façon la plus équitable de surveiller le temps CPU total - par utilisateur?

25

Sur un système multi-utilisateur, je veux mesurer l'utilisation du processeur de chaque utilisateur en quelques secondes de temps processeur. Aux fins de cette mesure, je suppose que si un PID appartient à un utilisateur, cet utilisateur est à l'origine du temps CPU - c'est-à-dire que j'ignore les démons et le noyau.

Actuellement, je fais cela, toutes les cinq secondes:

  1. Obtenez chaque utilisateur et les PID qu'ils utilisent via ps aux
  2. Pour chaque PID, obtenez xla somme de utime, cutime, stime et cstime de/proc/[pid]/stat
  3. calculer t = x / interval(l'intervalle n'est pas toujours exactement 5 secondes en cas de charge élevée)

Si je lance cela, j'obtiens des valeurs sensées. Par exemple: un utilisateur de ce système tournait en python ( while True: pass) et le système affichait environ 750 millisecondes de temps processeur par seconde. Lorsque le système s'est bloqué un peu, il a signalé 1 600 ms pour une inversion d'une seconde. Ce qui semble juste, mais je comprends que ces valeurs peuvent être trompeuses, d'autant plus que je ne les comprends pas vraiment .

Voici donc ma question:

Quelle est une façon juste et correcte de mesurer la charge CPU par utilisateur?

La méthode doit être assez précise. Il peut y avoir plusieurs centaines d'utilisateurs sur ce système, donc extraire des pourcentages ne ps auxsera pas assez précis, en particulier pour les threads de courte durée que de nombreux logiciels aiment faire apparaître.

Bien que cela puisse être compliqué, je sais absolument que c'est possible. C'était mon point de départ:

Le noyau garde une trace du temps de création des processus ainsi que du temps CPU qu'il consomme pendant sa durée de vie. A chaque horloge, le noyau met à jour le temps en jiffies que le processus actuel a passé en système et en mode utilisateur. - (du projet de documentation Linux )

La valeur que je recherche est le nombre de secondes (ou de jiffies) qu'un utilisateur a passé sur le CPU, et non un pourcentage de la charge du système ou de l'utilisation du processeur.

Il est important de mesurer le temps CPU pendant que les processus sont toujours en cours d'exécution. Certains processus ne dureront qu'une demi-seconde, d'autres dureront plusieurs mois - et nous devons intercepter les deux types, afin de pouvoir tenir compte du temps CPU des utilisateurs avec une granularité fine.

Stefano Palazzo
la source
1
500 points de réputation: de bonnes chances pour les débutants
Tachyons
Un peu hors de ma ligue, mais une question très intéressante alors j'ai creusé un peu et trouvé quelque chose qui, je l'espère, est au moins utile pour vous aider à résoudre ce problème: stackoverflow.com/a/1424556/905573
kingmilo
1
vous savez toppeut faire le mode batch? top -b -n 1 -u {user} | awk 'NR>7 { sum += $9; } END { print sum; }'devrait montrer la charge pour {user} à ce moment.
Rinzwind

Réponses:

11

On dirait que vous avez besoin de la comptabilité des processus.

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

Sur Ubuntu, les outils de comptabilité des processus sont dans le acctpackage Installer acct

Pour obtenir un rapport par utilisateur, exécutez

sa -m
Alan Bell
la source
Malheureusement, cela ne fonctionnera pas pour moi car "sa" ne comptera pas les processus de longue durée. Ce dont j'ai besoin (je pense), c'est d'un moyen de détecter les processus en cours de démarrage et d'arrêt, et d'enregistrer leur temps processeur lorsqu'ils quittent, ainsi que lorsqu'ils sont en cours d'exécution.
Stefano Palazzo
@StefanoPalazzo Je crois que c'est le meilleur que vous obtiendrez. Augmentez-le avec des temps d'exécution des processus à partir de /proc/[pid]/stat.
ændrük
Il s'avère que la plupart de tous les processus seront correctement pris en compte par sa(.ps.gz) . Et j'ai également un bon moyen «d'estimer» ces processus de longue durée, avant d'obtenir finalement une valeur précise pour ceux-ci également. Nous allons donc l'utiliser après tout, et je suis plus qu'heureux d'attribuer la prime à votre réponse. Merci beaucoup!
Stefano Palazzo
3

Cela donnera une ligne pour chaque utilisateur montrant le nom d'utilisateur et leur temps total de processeur:

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
la source
2

L'une des réponses les plus évidentes consiste à simplement étendre ce que vous faites actuellement.

Je suis tombé sur ce processus de surveillance pour utiliser les scripts bash et mysql pour suivre le temps processeur des utilisateurs, mais il a été réparti sur une période beaucoup plus longue que celle dont vous parliez.

J'espère que cela peut vous donner plus d'idées sur la direction dans laquelle vous cherchez à vous diriger.

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

Linztm
la source
0

Cela gérera également les processus qui ont été en cours d'exécution pendant des jours ... vous ne savez pas comment vous étendre pendant des semaines / mois / années ..

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
la source