系统性能监控-psutil功能详解
生活随笔
收集整理的這篇文章主要介紹了
系统性能监控-psutil功能详解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
psutil是一個跨平臺的庫,用于在Python中檢索有關運行進程和系統利用率(CPU,內存,磁盤,網絡,傳感器)的信息。它主要用于系統監視,分析,限制進程資源和運行進程的管理。它實現了UNIX命令行工具提供的許多功能,例如:ps,top,lsof,netstat,ifconfig,who,df,kill,free,nice,ionice,iostat,iotop,uptime,pidof,tty,taskset,pmap。
//安裝psutil pip install psutil //若上面安裝失敗可以嘗試下面 pip install psutil -i https://pypi.python.org/simple/獲取CPU信息
psutil.cpu_count() #獲取CPU個數 psutil.cpu_count(logical=False) psutil.cpu_stats() #以命名元組的形式返回各種CPU統計信息: 參數信息ctx_switches: 啟動以來上下文切換的次數(自愿+非自愿)。interrupts: 自啟動以來中斷的次數。soft_interrupts:自啟動以來,軟件中斷的次數。在Windows和SunOS上總是設置為0。soft_interrupts:自啟動以來,系統調用次數。在Linux上總是設置為0psutil.cpu_count() # 邏輯CPU核數 psutil.cpu_count(logical=False) # 物理CPU核數 psutil.cpu_times() # CPU的用戶、系統、空閑時間 psutil.cpu_percent(percpu=True) # 獲取每個CPU的使用率,類似TOP命令 top = [psutil.cpu_percent(interval=i, percpu=True) for i in range(10)] #設置每秒刷新時間間隔,統計十次的結果 psutil.getloadavg()將過去1、5和15分鐘內的平均系統負載作為一個元組返回。負載表示處于可運行狀態的進程,要么使用CPU,要么等待使用CPU(例如,等待磁盤I/O)。在UNIX系統中,這依賴于os.getloadavg。在Windows上,這是通過使用Windows API來模擬的,該API生成一個線程,該線程在后臺持續運行,并每5秒更新一次負載,模擬UNIX行為。因此,第一次調用它時,在接下來的5秒內,它將返回一個無意義的(0.0,0.0,0.0)元組。返回的數字只有與系統上安裝的CPU內核數量相關時才有意義。例如,在一個有10個CPU核心的系統上,3.14意味著在過去的N分鐘內系統負載為31.4%。實例:
""" 獲取cpu信息,負載、使用率信息 """ def get_cpuinfo():cpuInfo={}try:ostype = get_ostype()if ostype == "Linux":#獲取cpu使用率cpuuse_1 = psutil.cpu_percent()cpuuse = str(cpuuse_1)log_info(LOG_LOCATE(), "cpuuse:%s" % (cpuuse))#獲取cpu負載f = open("/proc/loadavg")con = f.read().split()f.close()cpuload = con[0] +'/'+con[1]+'/'+ con[2]cpuInfo['cpuUse'] = cpuusecpuInfo['cpuLoad_1'] = con[0]cpuInfo['cpuLoad_5'] = con[1]cpuInfo['cpuLoad_15'] = con[2]else:#獲取cpu相關信息#logic_count = psutil.cpu_count()#py_conut = psutil.cpu_count(logical=False)#log_info(LOG_LOCATE(), "logic_count:%d, py_conut:%d" % (logic_count, py_conut))#獲取cpu使用率try:cpuuse_1 = psutil.cpu_percent()cpuuse_2 = psutil.cpu_percent(percpu=True)log_info(LOG_LOCATE(), "cpuuse_1:%s, cpuuse_2:%s" % (cpuuse_1, cpuuse_2))except Exception as e:log_info(LOG_LOCATE(), "get cpu percent info error!")cpuuse_1 = 0.0cpuuse_2 = 0.0if cpuuse_1 > 90.0:cpuuse = str(cpuuse_2[0])if cpuuse == "0.0":cpuuse = "0.1"else:cpuuse = str(cpuuse_1)try:ptemp = os.popen("wmic cpu get loadpercentage")x = ptemp.read()log_info(LOG_LOCATE(), "-1-get cpuinfo str x:%s" % (x))str1 = re.split('\W+', x)if str1[-2] != " " and str1[-2] != "" and str1[-2].isspace() == False:if str1[-2] != "100":cpuInfo['cpuUse'] = cpuusecpuInfo['cpuLoad_1'] = str1[-2]cpuInfo['cpuLoad_5'] = str1[-2]cpuInfo['cpuLoad_15'] = str1[-2]else:if str1[-3] != " " and str1[-3] != "" and str1[-3].isspace() == False:cpuInfo['cpuUse'] = cpuusecpuInfo['cpuLoad_1'] = str1[-3]cpuInfo['cpuLoad_5'] = str1[-3]cpuInfo['cpuLoad_15'] = str1[-3]else:cpuInfo['cpuUse'] = cpuusecpuInfo['cpuLoad_1'] = str1[-2]cpuInfo['cpuLoad_5'] = str1[-2]cpuInfo['cpuLoad_15'] = str1[-2]else:log_info(LOG_LOCATE(), "-1-get cpu percent error!")ptemp.close()except Exception as e:log_info(LOG_LOCATE(), "-2-get cpu percent error!")except Exception as e:log_info(LOG_LOCATE(), "-1-get cpu info error")log_info(LOG_LOCATE(), "getcpuinfo:",cpuInfo)return cpuInfo?獲取內存信息
psutil.virtual_memory() #獲取內存統計數據,單位bytes 參數:total: 總物理內存(互斥交換)。available: 可以立即分配給進程而不需要系統進入交換區。這是通過根據平臺對不同的內存值求和計算出來的,它應該用于以跨平臺的方式監視實際的內存使用情況。其他指標:used: 使用的內存,根據平臺計算不同,僅用于信息目的。完全空閑不一定匹配使用。free:內存根本沒有被使用(0),隨時可用;注意,這并沒有反映實際可用的內存(而是使用可用的內存)。總使用量不一定匹配空閑。active (UNIX): 當前使用的或最近使用的內存,所以它在RAM中。inactive (UNIX): 標記為未使用的內存。buffers (Linux, BSD): 緩存文件系統元數據之類的東西。cached (Linux, BSD): 緩存各種東西。shared (Linux, BSD): 多個進程可以同時訪問的內存。slab (Linux): 內核內的數據結構緩存。wired (BSD, macOS): 被標記為始終保持在RAM中的內存。它從未移動到磁盤上。 psutil.swap_memory() # 獲取swap的統計數據 參數:total:總交換內存(以字節為單位)used:使用交換內存(以字節為單位)free:空閑交換內存(以字節為單位)percent:使用百分比,計算公式為(total - available) / total * 100sin: 系統從磁盤交換進來的字節數(累計)sout: 系統從磁盤交換出的字節數(累計) """ 獲取mem信息,內存總大小、剩余內存、內存使用率(M) """ def get_meminfo():memInfo={}ostype = get_ostype()if ostype == "Linux":try:memInfo['total'] = str(round(psutil.virtual_memory().total / (1024.0 * 1024.0), 1))#mem的free沒有加psutil.virtual_memory().sharedmemInfo['free'] = str(round(((psutil.virtual_memory().free + psutil.virtual_memory().buffers\+ psutil.virtual_memory().cached)) / (1024.0 * 1024.0), 1))#memInfo['used'] = psutil.virtual_memory().percentexcept Exception as e:log_info(LOG_LOCATE(), "get memInfo error")else:#windows memfree待確認try:memInfo['total'] = str(round(psutil.virtual_memory().total / (1024.0 * 1024.0), 1))#mem的free沒有加psutil.virtual_memory().sharedmemInfo['free'] = str(round((psutil.virtual_memory().free) / (1024.0 * 1024.0), 1))#memInfo['used'] = psutil.virtual_memory().percentexcept Exception as e:log_info(LOG_LOCATE(), "get memInfo error")#print("memInfo:%s" % (memInfo))return memInfo獲取磁盤信息
psutil.disk_partitions() #獲取磁盤分區信息 psutil.disk_usage("/") # 獲取分區使用情況, psutil.disk_io_counters() #磁盤IO情況 def get_OsDiskInfo():type = get_ostype()if type == "Linux":get_diskinfo("/opt") #磁盤信息else:get_diskinfo("C:/") #磁盤信息""" 獲取disk信息,磁盤大小、剩余磁盤大小、磁盤使用率 """ def get_diskinfo(diskDir):#/root, /opt, /swap, /var, /home #C:/, D:/diskInfo = {}p = psutil.disk_usage(diskDir)diskInfo['dir'] = diskDirdiskInfo['size'] = str(int(p.total / (1024.0 * 1024.0)))diskInfo['used'] = str(int(p.used / (1024.0 * 1024.0)))diskInfo['percent'] = psutil.disk_usage(diskDir).percentlog_info(LOG_LOCATE(), "diskinfo",diskInfo)return diskInfo?獲取網絡信息
psutil.net_if_stats() # 獲取網卡接口狀態 參數:isup: 一個bool,指示NIC是否已啟動并正在運行。duplex: 雙工通信類型;它可以是NIC_DUPLEX_FULL、NIC_DUPLEX_HALF或NIC_DUPLEX_UNKNOWN。speed: 網卡速度以兆比特(MB)表示,如果它不能被確定(如' localhost '),它將被設置為0。mtu: NIC的最大傳輸單元,以字節表示。 psutil.net_if_stats().get("en0") #獲取單個網卡en0的狀態 snicstats(isup=True, duplex=, speed=0, mtu=1500) psutil.net_if_addrs() # 獲取所有網卡的地址信息 參數:family: 地址族,可以是 AF_INET或AF_INET6或psutil.AF_LINK,它指的是MAC地址。address: 主網卡地址(總是設置)。netmask: 網絡掩碼地址(可能沒有)。broadcast: 廣播地址(可能沒有)。ptp: 表示“點對點”;它是點到點接口(通常是VPN)上的目標地址。廣播和ptp是互斥的。可能沒有。 # 獲取en0網卡的地址, 這里包括mac和ipv6地址 psutil.net_if_addrs().get("en0"): psutil.net_io_counters() # 獲取網絡讀寫字節/包的個數 參數:bytes_sent:發送的字節數bytes_recv:收到的字節數packets_sent:發送的數據包數packets_recv:收到的數據包數errin:收到錯誤的總數errout:發送時的錯誤總數dropin:丟棄的傳入數據包總數dropout:被丟棄的傳出數據包總數(在MacOS和BSD上總是為0) psutil.net_connections() # 獲取網絡連接信息,注意這里需要root權限。 """ 獲取設備網卡收發速率 """ def get_key():key_info = psutil.net_io_counters(pernic=True).keys() #獲取網卡名稱recv = {}sent = {}for key in key_info:recv.setdefault(key, psutil.net_io_counters(pernic=True).get(key).bytes_recv) #各網卡接收的字節數sent.setdefault(key, psutil.net_io_counters(pernic=True).get(key).bytes_sent) #各網卡發送的字節數return key_info, recv, sent def get_rate(func):key_info, old_recv, old_sent = func() #前5s收集的數據time.sleep(5)key_info, now_recv, now_sent = func() #當前所收集的數據net_in = {}net_out = {}for key in key_info:net_in.setdefault(key, (now_recv.get(key) - old_recv.get(key))/5) #每秒接收速率net_out.setdefault(key, (now_sent.get(key) - old_sent.get(key))/5) #每秒發送速率return key_info, net_in, net_outdef get_netinfo():try:netInfo = {}key_info, net_in, net_out = get_rate(get_key)#獲取網卡收發速率bytesnetInfo["Rx_rate"] = net_innetInfo["Tx_rate"] = net_outexcept Exception as e:log_info(LOG_LOCATE(), "get ipInfo error")return netInfo?獲取進程信息:
psutil.pids() # 獲取所有進程IDpsutil.Process(61) # 獲取指定PID的進程信息 psutil.Process(45573).exe() # 獲取進程的exe路徑 psutil.Process(45573).name() # 獲取進程名稱 psutil.Process(45573).cmdline() # 獲取進程啟動的命令 psutil.Process(45573).num_threads() # 獲取進程的線程數量 psutil.Process(45573).environ() # 獲取進程的環境變量信息 psutil.Process( pid=無) #表示具有給定pid的 OS 進程。如果省略 pid,則使用當前進程pid ( os.getpid )。NoSuchProcess如果pid不存在則引發。在 Linux 上, pid還可以引用線程 ID(方法返回的id字段 threads())。#訪問此類的方法時,請始終準備好捕獲 NoSuchProcess和AccessDenied異常。 hash builtin 可用于此類的實例,以便隨著時間的推移明確識別進程(哈希由混合進程 PID + 創建時間確定) pid # 進程PID。這是該類的唯一(只讀)屬性。 ppid( ) #進程父 PID。在 Windows 上,返回值在第一次調用后被緩存。不在 POSIX 上,因為如果進程變成僵尸,ppid 可能會改變 另見parent()和parents()方法。 name( ) #進程名稱。在 Windows 上,返回值在第一次調用后被緩存。不在 POSIX 上,因為進程名稱可能會更改。另請參閱如何按名稱查找進程。 exe( ) #進程可執行為絕對路徑。在某些系統上,這也可能是一個空字符串。返回值在第一次調用后被緩存 status( ) #當前進程狀態為字符串。返回的字符串是 psutil.STATUS_*常量之一。 num_threads( ) #此進程當前使用的線程數(非累積)。 num_fds( ) #此進程當前打開的文件描述符數(非累積)。 可用性:UNIX memory_info( ) #根據表示有關進程的內存信息的平臺,返回具有可變字段的命名元組。所有平臺上可用的“便攜式”字段是rss和vms。所有數字都以字節表示。 is_running( ) #返回當前進程是否在當前進程列表中運行。這在進程消失并且它的 PID 被另一個進程重用的情況下也是可靠的,因此它必須優于doing psutil.pid_exists(p.pid)。 """ 根據名稱查找進程 """ def find_procs_by_name(name):"Return a list of processes matching 'name'."ls = []for p in psutil.process_iter(["name", "exe", "cmdline"]):if name == p.info['name'] or \p.info['exe'] and os.path.basename(p.info['exe']) == name or \p.info['cmdline'] and p.info['cmdline'][0] == name:ls.append(p)return ls""" 獲取進程運行信息 """ def get_procinfo(pidName, time_range, ipAddr, mc_pub_time):procInfo={}servList = []servInfoToDbList = []time_cnt = int(time_range)/int(mc_pub_time)statlist = find_procs_by_name(pidName)print("procinfo:",statlist,"time_cnt:",time_cnt,"size:",len(statlist))if(statlist == "" or statlist == " " or len(statlist) == 0):procInfo['srevStatus'] = "ABNOMAL"procInfo['time'] = int(time.time())for p in statlist:print("pid:",p.pid,"status:",p.status(),"name:",p.name())if(p.is_running()):procInfo['srevStatus'] = "NOMAL"procInfo['time'] = int(time.time())else:procInfo['srevStatus'] = "ABNOMAL"procInfo['time'] = int(time.time())servInfoToDbList.append(procInfo)return servInfoToDbListif __name__ == '__main__':print(get_procinfo("QQ.exe", "10", "127.0.0.1", "6"))?其他信息
psutil.boot_time() #返回系統啟動時間(以秒為單位)。 psutil.users() #將當前連接到系統上的用戶作為命名元組列表返回 參數:user: 用戶的名稱。terminal: 與用戶關聯的tty或偽tty(如果有的話),否則為None。host: 與條目關聯的主機名(如果有的話)。started: 創建時間作為自紀元以來以秒為單位表示的浮點數。pid: 登錄進程的pid(如sshd、tmux、gdm-session-worker等)。在Windows和OpenBSD中,這總是設置為None。 """ 獲取系統時間 int """ def get_systimeinfo():sysTimeInfo={}now_time = int(time.time())sysTimeInfo["time"] = now_timereturn sysTimeInfodef get_sysTime():"""獲取系統時間"""try:timeinfo = get_systimeinfo()sysTime = timeinfo["time"]log_info(LOG_LOCATE(), "sysTime:%d" % (sysTime))except Exception as e:log_info(LOG_LOCATE(), "get systime info error")return sysTime?psutil模塊中傳感器等其他功能可以查看官方文檔:
psutil documentation — psutil 5.9.1 documentation
https://github.com/giampaolo/psutil?
總結
以上是生活随笔為你收集整理的系统性能监控-psutil功能详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SINOVATION助力企业走向“智造”
- 下一篇: 国内主流PHP语言的CMS数据负载测评报