Comment obtenir L'utilisation actuelle du CPU et de la RAM en Python?
Quelle est votre méthode préférée pour obtenir l'état actuel du système (CPU actuel, RAM, espace disque libre, etc.) en Python? Points Bonus pour les plateformes * nix et Windows.
Il semble y avoir quelques méthodes d'extraction que de ma recherche:
-
en utilisant une bibliothèque telle que PSI (qui semble actuellement non activement développé et non pris en charge sur une plate-forme multiple) ou quelque chose comme pystatgrab (de nouveau aucune activité depuis 2007 il semble et aucun soutien pour Windows).
-
utilisant un code spécifique à la plate-forme tel que
os.popen("ps")
ou similaire pour les systèmes *nix etMEMORYSTATUS
dansctypes.windll.kernel32
(voir cette recette sur ActiveState ) pour la plate-forme Windows. On pourrait mettre une classe Python avec tous ces morceaux de code.
ce n'est pas que ces méthodes sont mauvaises, mais y a-t-il déjà une façon bien supportée et multi-plateforme de faire la même chose?
11 réponses
La psutil bibliothèque qui vous donnera quelques informations sur le système (CPU / Mémoire d'utilisation) sur une variété de plates-formes:
psutil est un module fournissant une interface pour extraire des informations sur les processus en cours d'exécution et l'utilisation du système (CPU, Mémoire) d'une manière portable en utilisant Python, mettant en œuvre de nombreuses fonctionnalités offertes par des outils tels que ps, top et Windows task manager.
il soutient actuellement Linux, Windows, OSX, Sun Solaris, FreeBSD, OpenBSD et NetBSD, les architectures 32 et 64 bits, avec des versions Python de 2.6 à 3.5 (les utilisateurs de Python 2.4 et 2.5 peuvent utiliser la version 2.1.3).
utiliser la bibliothèque psutil . Pour moi sur Ubuntu, pip installé 0.4.3. Vous pouvez vérifier votre version de psutil en faisant ceci en Python:
from __future__ import print_function
import psutil
print(psutil.__version__)
Pour obtenir un peu de mémoire et de CPU stats:
from __future__ import print_function
import psutil
print(psutil.cpu_percent())
print(psutil.virtual_memory()) # physical memory usage
j'aime aussi faire ceci:
import os
import psutil
pid = os.getpid()
py = psutil.Process(pid)
memoryUse = py.memory_info()[0]/2.**30 # memory use in GB...I think
print('memory use:', memoryUse)
qui donne l'utilisation courante de la mémoire de votre script Python.
il y a quelques exemples plus approfondis sur le pypi page pour 4.3.0 et 0.5.0 .
Pour Ubuntu 16 et 14, l'installation à partir de pip m'a donné la version 4.3.0, qui n'a pas la méthode phymem_usage (). Pour obtenir 0.5.0 , vous pouvez être en mesure de faire pip install psutil==0.5.0
, ou télécharger le tar.GZ file , puis do
tar -xvzf psutil-0.5.0.tar.gz
cd psutil-0.5.0
sudo python setup.py install
ci-dessous codes, sans bibliothèques externes travaillé pour moi. J'ai testé à Python 2.7.9
utilisation CPU
import os
CPU_Pct=str(round(float(os.popen('''grep 'cpu ' /proc/stat | awk '{usage=(+)*100/(++)} END {print usage }' ''').readline()),2))
#print results
print("CPU Usage = " + CPU_Pct)
et utilisation de la mémoire vive, Total, utilisé et libre
import os
mem=str(os.popen('free -t -m').readlines())
"""
Get a whole line of memory output, it will be something like below
[' total used free shared buffers cached\n',
'Mem: 925 591 334 14 30 355\n',
'-/+ buffers/cache: 205 719\n',
'Swap: 99 0 99\n',
'Total: 1025 591 434\n']
So, we need total memory, usage and free memory.
We should find the index of capital T which is unique at this string
"""
T_ind=mem.index('T')
"""
Than, we can recreate the string with this information. After T we have,
"Total: " which has 14 characters, so we can start from index of T +14
and last 4 characters are also not necessary.
We can create a new sub-string using this information
"""
mem_G=mem[T_ind+14:-4]
"""
The result will be like
1025 603 422
we need to find first index of the first space, and we can start our substring
from from 0 to this index number, this will give us the string of total memory
"""
S1_ind=mem_G.index(' ')
mem_T=mem_G[0:S1_ind]
"""
Similarly we will create a new sub-string, which will start at the second value.
The resulting string will be like
603 422
Again, we should find the index of first space and than the
take the Used Memory and Free memory.
"""
mem_G1=mem_G[S1_ind+8:]
S2_ind=mem_G1.index(' ')
mem_U=mem_G1[0:S2_ind]
mem_F=mem_G1[S2_ind+8:]
print 'Summary = ' + mem_G
print 'Total Memory = ' + mem_T +' MB'
print 'Used Memory = ' + mem_U +' MB'
print 'Free Memory = ' + mem_F +' MB'
une doublure pour L'utilisation de la RAM avec dépendance stdlib:
import os
tot_m, used_m, free_m = map(int, os.popen('free -t -m').readlines()[-1].split()[1:])
voici quelque chose que j'ai assemblé il y a un moment, c'est windows seulement, mais peut vous aider à obtenir une partie de ce que vous devez faire.
dérivé de: "pour sys disponible mem" http://msdn2.microsoft.com/en-us/library/aa455130.aspx
" informations de processus individuelles et exemples de script python" http://www.microsoft.com/technet/scriptcenter/scripts/default.mspx?mfr=true
NOTE: le Interface/processus WMI est également disponible pour effectuer des tâches similaires Je ne l'utilise pas ici parce que la méthode actuelle couvre mes besoins, mais si un jour il est nécessaire d'étendre ou d'améliorer cela, alors pourrait vouloir étudier les outils WMI disponibles.
WMI pour python:
http://tgolden.sc.sabren.com/python/wmi.html
le code:
'''
Monitor window processes
derived from:
>for sys available mem
http://msdn2.microsoft.com/en-us/library/aa455130.aspx
> individual process information and python script examples
http://www.microsoft.com/technet/scriptcenter/scripts/default.mspx?mfr=true
NOTE: the WMI interface/process is also available for performing similar tasks
I'm not using it here because the current method covers my needs, but if someday it's needed
to extend or improve this module, then may want to investigate the WMI tools available.
WMI for python:
http://tgolden.sc.sabren.com/python/wmi.html
'''
__revision__ = 3
import win32com.client
from ctypes import *
from ctypes.wintypes import *
import pythoncom
import pywintypes
import datetime
class MEMORYSTATUS(Structure):
_fields_ = [
('dwLength', DWORD),
('dwMemoryLoad', DWORD),
('dwTotalPhys', DWORD),
('dwAvailPhys', DWORD),
('dwTotalPageFile', DWORD),
('dwAvailPageFile', DWORD),
('dwTotalVirtual', DWORD),
('dwAvailVirtual', DWORD),
]
def winmem():
x = MEMORYSTATUS() # create the structure
windll.kernel32.GlobalMemoryStatus(byref(x)) # from cytypes.wintypes
return x
class process_stats:
'''process_stats is able to provide counters of (all?) the items available in perfmon.
Refer to the self.supported_types keys for the currently supported 'Performance Objects'
To add logging support for other data you can derive the necessary data from perfmon:
---------
perfmon can be run from windows 'run' menu by entering 'perfmon' and enter.
Clicking on the '+' will open the 'add counters' menu,
From the 'Add Counters' dialog, the 'Performance object' is the self.support_types key.
--> Where spaces are removed and symbols are entered as text (Ex. # == Number, % == Percent)
For the items you wish to log add the proper attribute name in the list in the self.supported_types dictionary,
keyed by the 'Performance Object' name as mentioned above.
---------
NOTE: The 'NETFramework_NETCLRMemory' key does not seem to log dotnet 2.0 properly.
Initially the python implementation was derived from:
http://www.microsoft.com/technet/scriptcenter/scripts/default.mspx?mfr=true
'''
def __init__(self,process_name_list=[],perf_object_list=[],filter_list=[]):
'''process_names_list == the list of all processes to log (if empty log all)
perf_object_list == list of process counters to log
filter_list == list of text to filter
print_results == boolean, output to stdout
'''
pythoncom.CoInitialize() # Needed when run by the same process in a thread
self.process_name_list = process_name_list
self.perf_object_list = perf_object_list
self.filter_list = filter_list
self.win32_perf_base = 'Win32_PerfFormattedData_'
# Define new datatypes here!
self.supported_types = {
'NETFramework_NETCLRMemory': [
'Name',
'NumberTotalCommittedBytes',
'NumberTotalReservedBytes',
'NumberInducedGC',
'NumberGen0Collections',
'NumberGen1Collections',
'NumberGen2Collections',
'PromotedMemoryFromGen0',
'PromotedMemoryFromGen1',
'PercentTimeInGC',
'LargeObjectHeapSize'
],
'PerfProc_Process': [
'Name',
'PrivateBytes',
'ElapsedTime',
'IDProcess',# pid
'Caption',
'CreatingProcessID',
'Description',
'IODataBytesPersec',
'IODataOperationsPersec',
'IOOtherBytesPersec',
'IOOtherOperationsPersec',
'IOReadBytesPersec',
'IOReadOperationsPersec',
'IOWriteBytesPersec',
'IOWriteOperationsPersec'
]
}
def get_pid_stats(self, pid):
this_proc_dict = {}
pythoncom.CoInitialize() # Needed when run by the same process in a thread
if not self.perf_object_list:
perf_object_list = self.supported_types.keys()
for counter_type in perf_object_list:
strComputer = "."
objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator")
objSWbemServices = objWMIService.ConnectServer(strComputer,"root\cimv2")
query_str = '''Select * from %s%s''' % (self.win32_perf_base,counter_type)
colItems = objSWbemServices.ExecQuery(query_str) # "Select * from Win32_PerfFormattedData_PerfProc_Process")# changed from Win32_Thread
if len(colItems) > 0:
for objItem in colItems:
if hasattr(objItem, 'IDProcess') and pid == objItem.IDProcess:
for attribute in self.supported_types[counter_type]:
eval_str = 'objItem.%s' % (attribute)
this_proc_dict[attribute] = eval(eval_str)
this_proc_dict['TimeStamp'] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.') + str(datetime.datetime.now().microsecond)[:3]
break
return this_proc_dict
def get_stats(self):
'''
Show process stats for all processes in given list, if none given return all processes
If filter list is defined return only the items that match or contained in the list
Returns a list of result dictionaries
'''
pythoncom.CoInitialize() # Needed when run by the same process in a thread
proc_results_list = []
if not self.perf_object_list:
perf_object_list = self.supported_types.keys()
for counter_type in perf_object_list:
strComputer = "."
objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator")
objSWbemServices = objWMIService.ConnectServer(strComputer,"root\cimv2")
query_str = '''Select * from %s%s''' % (self.win32_perf_base,counter_type)
colItems = objSWbemServices.ExecQuery(query_str) # "Select * from Win32_PerfFormattedData_PerfProc_Process")# changed from Win32_Thread
try:
if len(colItems) > 0:
for objItem in colItems:
found_flag = False
this_proc_dict = {}
if not self.process_name_list:
found_flag = True
else:
# Check if process name is in the process name list, allow print if it is
for proc_name in self.process_name_list:
obj_name = objItem.Name
if proc_name.lower() in obj_name.lower(): # will log if contains name
found_flag = True
break
if found_flag:
for attribute in self.supported_types[counter_type]:
eval_str = 'objItem.%s' % (attribute)
this_proc_dict[attribute] = eval(eval_str)
this_proc_dict['TimeStamp'] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.') + str(datetime.datetime.now().microsecond)[:3]
proc_results_list.append(this_proc_dict)
except pywintypes.com_error, err_msg:
# Ignore and continue (proc_mem_logger calls this function once per second)
continue
return proc_results_list
def get_sys_stats():
''' Returns a dictionary of the system stats'''
pythoncom.CoInitialize() # Needed when run by the same process in a thread
x = winmem()
sys_dict = {
'dwAvailPhys': x.dwAvailPhys,
'dwAvailVirtual':x.dwAvailVirtual
}
return sys_dict
if __name__ == '__main__':
# This area used for testing only
sys_dict = get_sys_stats()
stats_processor = process_stats(process_name_list=['process2watch'],perf_object_list=[],filter_list=[])
proc_results = stats_processor.get_stats()
for result_dict in proc_results:
print result_dict
import os
this_pid = os.getpid()
this_proc_results = stats_processor.get_pid_stats(this_pid)
print 'this proc results:'
print this_proc_results
http://monkut.webfactional.com/blog/archive/2009/1/21/windows-process-memory-logging-python
"... état actuel du système (CPU actuel, RAM, espace disque libre, etc.) "Et" *plates-formes nix et Windows " peuvent être une combinaison difficile à réaliser.
les systèmes d'exploitation sont fondamentalement différents dans la façon dont ils gèrent ces ressources. En effet, ils diffèrent dans les concepts de base comme définir ce qui compte comme système et ce qui compte comme temps d'application.
"espace disque Libre"? Ce qui compte comme "espace disque?"Toutes les partitions de tous les appareils? Qu'en est-il des partitions étrangères dans un environnement multi-boot?
Je ne pense pas qu'il y ait un consensus assez clair entre Windows et *nix qui rende cela possible. En effet, il n'y a peut-être même pas de consensus entre les différents systèmes d'exploitation appelés Windows. Existe-t-il une API Windows unique qui fonctionne à la fois pour XP et Vista?
j'ai l'impression que ces réponses ont été écrites pour Python 2, et dans tous les cas personne n'a mentionné le paquet standard resource
disponible pour Python 3. Il fournit des commandes pour obtenir la ressource limits d'un processus donné (le processus Python appelant par défaut). Ce n'est pas la même chose que d'obtenir le utilisation des ressources par le système dans son ensemble, mais il pourrait résoudre certains des mêmes des problèmes comme par exemple "je veux m'assurer que je n'utilise que X beaucoup de RAM avec ce script."
vous pouvez utiliser psutil ou psmem avec subprocess exemple de code
import subprocess
cmd = subprocess.Popen(['sudo','./ps_mem'],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
out,error = cmd.communicate()
memory = out.splitlines()
référence http://techarena51.com/index.php/how-to-install-python-3-and-flask-on-linux /
nous avons choisi d'utiliser la source d'information habituelle pour cela parce que nous pouvions trouver des fluctuations instantanées dans la mémoire libre et nous avons pensé que la source de données meminfo était utile. Cela nous a également aidé à obtenir quelques paramètres plus liés qui ont été prédéfinis.
Code
import os
....
memory_usage = os.popen("cat /proc/meminfo").read()
sortie de référence (nous avons dépouillé toutes les lignes pour une analyse plus poussée)
MemTotal: 1014500 kB MemFree: 562680 kB Memav available: 646364 kB Tampons: 15144 ko de Cache: 210720 ko SwapCached: 0 ko Active: 261476 ko Inactif: 128888 kB actif (anon): 167092 kB inactif (anon): 20888 kB Active(fichier): 94384 ko Inactif(fichier): 108000 ko Unevictable: 3652 ko Mlocked: 3652 ko SwapTotal: 0 ko SwapFree: 0 ko Sale: 0 ko écriture Différée: 0 kB AnonPages: 168160 kB Maped: 81352 kB Shmem: 21060 kB Slab: 34492 kB SReclaimable: 18044 kB SUnreclaim: 16448 kB KernelStack: 2672 kB PageTables: 8180 ko NFS_Unstable: 0 ko Bounce: 0 ko WritebackTmp: 0 ko CommitLimit: 507248 kB Committed_AS: 1038756 kB VmallocTotal: 34359738367 kB VmallocUsed: 0 kB VmallocChunk: 0 kB Hardcarecorrupted: 0 kB AnonHugePages: 88064 kB CmaTotal: 0 kB CmaFree: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 43008 kB DirectMap2M :1005568 kB
ce script pour L'usage CPU:
import os
def get_cpu_load():
""" Returns a list CPU Loads"""
result = []
cmd = "WMIC CPU GET LoadPercentage "
response = os.popen(cmd + ' 2>&1','r').read().strip().split("\r\n")
for load in response[1:]:
result.append(int(load))
return result
if __name__ == '__main__':
print get_cpu_load()
Je ne crois pas qu'il existe une bibliothèque multi-plateforme bien supportée. Rappelez-vous que Python lui-même est écrit en C de sorte que n'importe quelle bibliothèque va simplement prendre une décision intelligente au sujet du code snippet spécifique à L'OS à exécuter, comme vous l'avez suggéré ci-dessus.