samedi 12 février 2011

psutil: la bibliothèque Python pour monitorer les processus

Easy install / PIP
Si l'outil easy_install ou PIP (recommandé) n'est pas encore installer, référez-vous à l'article "Installer easy_install sous Ubuntu".
Cet outil est indispensable pour installer facilement des bibliothèques/paquets Pyhton.

La librairie psutil
La bibliothèque psutil de Pyhton contient toute une série d'utilitaires permettant de récupérer des informations relatives aux processus en court de fonctionnement sur le système.
Psutil est compatible avec de nombreux systèmes d'exploitation, cela inclus également Mac OS X et Windows :-)

Ne pas oublier d'utiliser SUDO pour installer une bibliothèque Python avec easy_install ou pip car le processus d'installation accède à des répertoires qui sont protégés en temps normal.

Utilisez la commande suivante pour installer psutil:
sudo easy_install psutil
sudo pip install psutil

Aide sur psutil
>>> import psutil
>>> help( psutil )
Voir aussi le projet de documentation sur Google Code (fourni également des exemples de structure).

Utiliser psutil
Lister tous les processus en cours de fonctionnement via un itérateur
>>> import psutil
>>> iter = psutil.process_iter()
>>> iter
<generator object process_iter at 0xb760d554>
>>> for process in iter:
...     print process.name

Voici un autre exemple qui ne s'intéresse qu'aux processus consommant plus de 4% du temps cpu.
>>> def filterCpu( process ):
...     return process.get_cpu_percent() > 4
... 
>>> pslist = psutil.get_process_list()
>>> consuming_pslist = filter( filterCpu, pslist )
>>> for process in consuming_pslist:
...     print process.name + " " + str( process.get_cpu_percent() )
...
plugin-container 27.3
gedit 0.0

Dans le résultat ci-dessus le pourcentage cpu affiché pour gEdit est de 0%, ce qui semble erroné de premier abord.
S'il en est ainsi, c'est parce qu'au moment de l'affichage, le processus ne consommait plus que 0% de cpu alors qu'il en consommait plus de 4% au moment de la constitution de la liste consuming_pslist.

Il faudrait donc capturer le pourcentage cpu pour pouvoir l'afficher.
Cela se fait à l'aide d'une "expression list" constituant une liste de tuple (l'object Process + capture de l'usage cpu).
Par exemple:
capturedCpu_pslist = [ (process, process.get_cpu_percent() ) for process in psutil.get_process_list() ]

>>> def filterCpu( processpro ):
...     return process.get_cpu_percent() > 4
... 
>>> capturedCpu_pslist = [ (process, process.get_cpu_percent() ) for process in psutil.get_process_list() ]
>>> def filterCapturedCpu( processCpuTuple ): 
...     return processCpuTuple[1] > 4
... 
>>> consumingCpu_pslist = filter( filterCapturedCpu, capturedCpu_pslist )
>>> for process, capturedCpu in consumingCpu_pslist:
...     print( '%s  capturedCpu=%d   currentCpu=%d' % ( process.name, capturedCpu, process.get_cpu_percent() ) )
... 
rhythmbox  capturedCpu=9   currentCpu=0
plugin-container  capturedCpu=28   currentCpu=18
python  capturedCpu=9   currentCpu=0

Quelques informations récupérées via psutil
Voici quelques exemples exploitant les informations de psutil tout en faisant la correspondance avec des commandes à exécuter dans le terminale.
Cela permet de se rendre compte de la stricte correspondance entre les informations de psutil et le fonctionnement du système d'exploitation.

Utilisation de la mémoire physique
>>> psutil.TOTAL_PHYMEM/1024 # transform bytes to kbytes3056648L
>>> psutil.used_phymem()/1024
1798832L
>>> psutil.avail_phymem()/1024
1257736
correspond aux informations de la commande free (section mem)
domeu@domeu-Lenovo:~$ free
             total       used       free     shared    buffers     cached
Mem:       3056648    1798504    1258144          0     162528     965768
-/+ buffers/cache:     670208    2386440
Swap:     12286972          0   12286972

Utilisation de la mémoire virtuelle
>>> psutil.total_virtmem()/1024 # transform bytes to kbytes12286972L
>>> psutil.used_virtmem()/1024
0L
>>> psutil.avail_virtmem()/1024
12286972L

correspond aux informations de la commande free (section swap)
domeu@domeu-Lenovo:~$ free
             total       used       free     shared    buffers     cached
Mem:       3056648    1795472    1261176          0     162400     963608
-/+ buffers/cache:     669464    2387184
Swap:     12286972          0   12286972

Utilisation de la mémoire d'un processus
Commençons par trouver le pid (process id) du processus python avec la commande suivante:
ps -ef | grep python

domeu@domeu-Lenovo:~$ ps -ef | grep python
UID        PID  PPID  C STIME TTY          TIME CMD
domeu    18958 15312  0 14:48 pts/0    00:00:02 python

Dans Pyhton, il est possible de retrouver l'object Process via un filtre sur psutil.get_process_list() OU en créant un object Process en lui passant le pid en paramètre.

>>> pyProcess = psutil.Process( 18958 )
>>> pyProcess.name
'python'
>>> pyProcess.get_cpu_percent()
0.0
>>> pyProcess.get_memory_percent()
0.18765654403123946
>>> pyProcess.get_memory_info() # RSS (Resident Set Size=process memory + data), VSZ (all memory, included library, cache, etc)meminfo(rss=5873664, vms=11493376)

Ce qui correspond aux informations de la commande
ps aux | grep python

domeu@domeu-Lenovo:~$ ps aux | grep python
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
domeu    18958  0.0  0.1  11220  5736 pts/0    S+   14:48   0:02 python

Utilisation avancée
Parmi les utilisations avancées de psutil, il y a l'opportunité de surveiller de lister les fichiers et les connections ouvertes par un processus.
Le site officiel et la documentation de l'API demontre d'ailleurs clairement cette capacité de psutil


Ressources

Aucun commentaire: