Psutil - Monitoreo del sistema
Psutil ayuda a monitorear los parámetros de funcionamiento del sistema operativo y de sus procesos, tales como el uso de memoria, frecuencia de trabajo, uso de redes, sensores internos, etc.
Primeros pasos
El paquete se instala desde el gestor PIP.
El nombre de módulo coincide con el del paquete , por ello se lo importa directamente:
Parámetros de Sistema
Para consultar parámetros del sistema psutil incluye un juego de funciones
CPU
frecuencias
Valores disponibles:Valores disponibles
campo | valor |
---|---|
current | frecuencia de trabajo actual (en MHz) |
min | frecuencia de trabajo mínima (en MHz) |
max | frecuencia de trabajo máxima (en MHz) |
Caso Linux, FreeBSD: pueden monitorearse todos los procesadores:
nucleos
Cuenta cuantos núcleos (cores) dispone el CPU:
Hint: núcleos físicos y lógicos
La relación entre núcleos físicos y núcleos lógicos es:
Ejemplo: un CPU con 2 núcleos físicos e 'HiperThreading' de 2 hilos simultáneos por core da 4 núcleos lógicos.
cpu_percent()
Permite calcular el porcentaje de uso promedio de todos los núcleos del CPU :
# porcentaje de exigencia del CPU
porcentaje_total = psutil.cpu_percent(
interval=None, # tiempo de referencia
percpu=False # resultado en lista de porcentajes , uno por *core*
)
Si no se indica un valor numérico para interval se toma de referencia la anterior llamada del método o en su defecto la importación del módulo. Es conveniente que entre ambas llamadas hayan pasado al menos 0.1 segundos para mejor precisión.
Ejemplo: demanda de CPU de una rutina completa
cpu_times()
Calcula los tiempos acumulados de procesamiento de cada núcleo lógico.
data_tiempos = psutil.cpu_times() # informacion de tiempo de procesamiento en segundos
Campos más habituales
campo | valor |
---|---|
user | tiempo usado en modo usuario (segundos) |
system | tiempo usado en modo kernel (segundos) |
Más informacion sobre cpu_times(): sitio oficial
Procesos
listado y verificacion
lista_pids = psutil.pids() # todos los PIDS activos encontrados
existe_proceso = psutil.pid_exists(pid) # verifica actividad
espera y eventos al cierre
# Espera al cierre de procesos indicados
psutil.wait_procs(
lista_pids, # lista de numeros de IDs
timeout=None, # tiempo de espera máximo
callback=None # manejador asignable -> se dispara con cada cierre
)
Memoria RAM
Campos principales:
campo | valor |
---|---|
total | memoria RAM total (en bytes) |
available | memoria RAM actualmente disponible (en bytes) |
percent | porcentaje de memoria usado |
Memoria SWAP
Campos principales:
campo | valor |
---|---|
total | memoria swap total (en bytes) |
used | memoria swap actualmente usado |
free | memoria swap libre |
percent | porcentaje de memoria swap usado |
sin | data escrita en disco (acumulativa) |
sout | data leida en disco (acumulativa) |
Discos
particiones
particiones_físicas = psutil.disk_partitions() # lista de particiones
for particion in particiones:
print(particion)
Contenido de listas:
campo | valor |
---|---|
device | ruta del dispositivo: 'C:\', '/dev/hda1', etc |
mountpoint | ruta montada_ '/', '/home', 'D:\', etc |
fstype | formato: NTFS, FAT, ext4, etc |
opt | informacion extra (dependiente del SO) |
espacio en disco
Contenido:
campo | valor |
---|---|
used | espacio usado (en bytes) |
free | espacio libre (en bytes) |
Ejemplo: estadísticas del disco o particion
ruta = "/"
uso_disco = psutil.disk_usage(ruta)
espacio_usado = uso_disco.used # espacio usado (en bytes)
espacio_libre = uso_disco.free # espacio libre (en bytes)
print(f"Ruta: {ruta}")
print(f"Espacio usado: {espacio_usado / (1000**3):.4} GiB")
print(f"Espacio libre: {espacio_libre / (1000**3):.4} GiB")
estadisticas de lectura/escritura
Las estadísticas de lectura y escritura se calculan con la función disk_io_counters():
Campos más importantes
campo | valor |
---|---|
read_count | Nº operaciones lectura |
write_count | Nº operaciones escritura |
read_bytes | data total leida (en bytes) |
write_bytes | data total escrita (en bytes) |
La información puede fragmentarse por partición con ayuda del argumento perdisk:
Uso de red
estadisticas globales
La información se condensa con la función net_io_counters():
Datos disponibles:
Campos disponibles
campo | valor |
---|---|
bytes_sent | bytes enviados |
bytes_recv | bytes recibidos |
packets_sent | paquetes enviados |
packets_recv | paquetes recibidos |
errin | errores enviados |
errout | errores recibidos |
dropin | paquetes descartados enviados |
dropout | paquetes descartados recibidos |
Ejemplo de uso: medicion del uso de datos por red
configuracion local
Data de direcion MAC, IP's, etc: función net_if_addrs()
canales
Estado de conexiones, velocidades de transmisión, tipos de transmisión, etc: función net_if_stats()
estadísticas (por canal)
Información de conexiones de socket local y remoto: IP's, puertos, tipo de socket, etc.
Sensores y ventiladores
# temperaturas del sistema en grados Celsius salvo indicacion contraria
data_temperatura = psutil.sensors_temperatures(fahrenheit=False)
# velocidad de ventiladores en RPM
data_ventiladores = psutil.sensors_fans() # '{}' si no hay información
Procesos específicos
La data de proceso se gestiona con la clase Process:
Esta clase asigna una serie de métodos para obtener la inforncion relevante del proceso: uso de memoria, procesamiento de CPU, conexiones IP, etc.Estadisticas de memoria
El método memory_info() da información sobre el consumo de memoria del proceso actua:
Campos más comunes:
Campos más habituales
campo | información |
---|---|
rss | uso de RAM en bytes |
vms | uso de SWAP en bytes |
Ejemplo de uso: uso de memoria por el proceso actual
proceso = psutil.Process()
info_memoria = proceso.memory_info()
info_memoria.rss # uso de RAM en bytes
info_memoria.vms # uso de SWAP en bytes
Estos campos son comunes para todos los sistemas operativos implementados. Los otros campos de información tienen nombres y disponibilidad que dependen del sistema operativo anfitrión.
Ver más información sobre memory_info(): sitio oficial
Estadisticas del procesamiento
Estado del proceso, núcleo ejecutante y núcleos habilitados para ejecutar:
proceso.status() # estado actual
proceso.cpu_num() # Nº procesador ejecutando el proceso
proceso.cpu_affinity() # Nº procesadores habilitados para ejecutar este proceso
Prioridad del proceso
La prioridad de los procesos son números que el sistema operativo tiene en cuenta a la hora de repartir el tiempo de ejecución de los núcleos del CPU entre los procesos activos.
La prioridad del proceso actual es accesible y modificable con el método nice():
En UNIX el valor va típicamente desde -20 (prioridad máxima) a 20(prioridad mínima).cpu_percent()
Permite calcular el porcentaje de uso de todos los CPUs por el programa actual (puede superar el 100%):
# porcentaje de exigencia del CPU
porcentaje_total = proceso.cpu_percent(interval=None, percpu=False) # (desde ultimo llamado)
Si no se indica un valor numérico para interval se toma de referencia la anterior llamada del método o en su defecto la importación del módulo. Es conveniente que entre ambas llamadas hayan pasado al menos 0.1 segundos para mejor precisión.
Ejemplo uso: demanda de CPU de una rutina completa
cpu_times()
Calcula los tiempos acumulados de procesamiento que demandó el proceso desde su inicio hasta el presente.
Campos más habituales:Campos más habituales
campo | valor |
---|---|
user | tiempo usado en modo usuario (segundos) |
system | tiempo usado en modo kernel (segundos) |
Más informacion sobre cpu_times(): sitio oficial
Arbol de procesos
# Identificador (ID)
pid = proceso.pid # ID del proceso
ppid = proceso.ppid() # ID del proceso padre
# data
data_padre = proceso.parent() # proceso padre
lista_padres = proceso.parents() # lista de procesos "padres"/"abuelos"/etc
lista_hijos = proceso.children(recursive=False) # lista de procesos hijos
Hilos (threads)
# hilos
data_hilos = proceso.threads() # informacion de los hilos 'namedtuple'
nro_hilos = proceso.num_threads() # numero hilos
Ruta de programa
Archivos
Da informacion de los archivos afectados por el proceso:
Campos habituales
campo | valor |
---|---|
path | ruta de archivo |
fd | nº descriptor (-1 en Windows) |
Variables de entorno
Usuario y Grupo
nombre_usuario = proceso.username() # usuario actual
data_usuario = proceso.uids() # informacion de usuario
data_usuario = proceso.gids() # informacion de grupo
Conexiones IP
Da información de los sockets ("zócalos" de conexión) creados por el proceso para las conexiones:
# información de sockets usados - lista de 'namedtuple'
lista_sockets = proceso.net_connections() # V > 0.6.0
lista_sockets = proceso.connections() # V < 0.6.0
Campos disponibles
campo | información |
---|---|
fd | descriptor del socket |
ladr | rutas IP del sistema |
radr | ruta IP del destinatario |
family | versión de rutas IP ("familia"): IPv4, IPv6, etc |
type | tipo de dirección: TCP / UDP / etc |
status | estado de la conexión |
Más información sobre net_connections(): sitio oficial
Manejo de señales
Métodos disponibles
método | señal equivalente | uso |
---|---|---|
send_signal( nro_signal) | {SIG} | le envía una señal al proceso |
suspend() | SIGSTOP | suspende el proceso (lo deja en espera) |
resume() | SIGCONT | reanuda el proceso |
wait(timeout=None) | --- | espera al cierre, tiempo de expiración en segundos |
terminate() | SIGTERM | termina el proceso |
kill() | SIGKILL | mata el proceso |
Ejemplo: ordenar el cierre de un proceso y esperar a su cumplimiento