Python 系統資源資訊獲取工具,你用過沒?

asyncins發表於2018-11-28

如果你需要通過 Python 程式碼來監控伺服器資源資訊,比如內容佔用情況、cpu 資源消耗以及資源不足傳送警報等,那麼這篇文章很適合你。

Python 系統資源資訊獲取工具,你用過沒?

香香的口味,你吃過沒?
辣辣的感覺,你嘗過沒?
網爆紅人的歌聲,你聽過沒?
Python 系統資源資訊獲取的工具,你用過沒?
真正的烤麵筋
可帶勁啦!~~~
讓你吃到真正的實惠!

不一樣的滋味!!!
複製程式碼

致敬那個不屈的男人(麵筋哥 程書林)

工具介紹

psutil(process and system utilities)是一個跨平臺的庫,github官方文件

我們可以用它來檢視系統執行程式以及資源利用率。它主要用於系統監控、過程資源分析和限制以及執行過程的管理。psutil 的主要功能結構如下圖所示

Python 系統資源資訊獲取工具,你用過沒?

它有三大功能模組,分別是 System related function、Processes 和 Windows Service。

psutil 實現了UNIX命令列工具提供的許多功能,比如 top、free、netstat、kill 等,並且還相容各大作業系統:

Python 系統資源資訊獲取工具,你用過沒?
psutil 可以說是系統管理老大哥或者運維小夥不可或缺的必備模組。

psutil 的安裝

我們可以一邊翻閱 psutil 的官方文件,一邊編寫程式碼,這樣就能夠更快的學習。

在 Python 環境下安裝,直接使用 pip 命令即可:

pip install psutil
複製程式碼

但是,如果你只希望當前使用者可用,而不是整個系統所有使用者都能使用,你就需要調整你的命令:

pip install -user psutil
複製程式碼

除此之外,它還提供瞭如 wget、curl 等多種安裝方式,具體可參閱文件的 install 部分,但是通常來說 pip install psutil 命令已經滿足我們的需求了。

系統相關操作

它為我們提供了一些系統常用的操作內容 可參閱文件。其中包括了 CPU、記憶體、磁碟、網路、感測器和程式等方面。

CPU 監控

可以通過 cpu_times 模組對 cpu 資源進行檢視,比如:

>>> import psutil
>>> psutil.cpu_times()
scputimes(user=477.29, nice=0.0, system=262.86, idle=6074.83)
複製程式碼

Python 系統資源資訊獲取工具,你用過沒?

cpu_times 中的引數有哪些含義呢?文件中也給出了具體的釋義

Python 系統資源資訊獲取工具,你用過沒?

翻譯一下,我們可以看到它給使用者提供了比較細緻的資訊監控:

將系統CPU時間作為命名元組返回。每個屬性表示CPU在給定模式下花費的秒數。屬性可用性因平臺而異:

user:正常程式在使用者模式下執行所花費的時間; 在Linux上,這還包括訪客時間
system:在核心模式下執行的程式所花費的時間
閒置:無所事事的時間
特定於平臺的欄位:

nice (UNIX):在使用者模式下執行的niced(優先順序)程式所花費的時間; 在Linux上,這還包括guest_nice時間
iowait (Linux):等待I / O完成所花費的時間
irq (Linux,BSD):服務硬體中斷所花費的時間
softirq (Linux):服務軟體中斷所花費的時間
steal (Linux 2.6.11+):在虛擬化環境中執行的其他作業系統所花費的時間
guest (Linux 2.6.24+):在Linux核心的控制下為客戶作業系統執行虛擬CPU所花費的時間
guest_nice (Linux 3.2.0+):執行niced guest虛擬機器所花費的時間(Linux核心控制下的來賓作業系統的虛擬CPU)
interrupt (Windows):服務硬體中斷所花費的時間(類似於UNIX上的“irq”)
dpc (Windows):服務延遲過程呼叫(DPC)所花費的時間;DPC是以比標準中斷低的優先順序執行的中斷。
複製程式碼

往下看還可以看到其他的 cpu 監控模組,比如我們最需要的 cpu 資源消耗百分比,cpu_percent(interval=None, percpu=False) 可以返回一個浮點數,表示當前系統範圍的CPU利用率百分比。當interval為> 0.0比較間隔之前和之後經過的系統CPU時間(阻塞)。當interval是0.0或None比較自上次呼叫或模組匯入後經過的系統CPU時間,立即返回。這意味著第一次呼叫它將返回一個無意義的0.0 值,你應該忽略它。在這種情況下,建議0.1在呼叫之間至少呼叫此函式的準確性。當percpu是True返回表示利用率的浮點數列表,以每個CPU的百分比表示。列表的第一個元素是指第一個CPU,第二個元素是第二個CPU,依此類推。列表的順序在呼叫之間是一致的。

而通過 cpu_count() 可以檢視 cpu 核心數量,它可以返回系統中 cpu 的數量(與 os.cpu_count 的返回相同)

Python 系統資源資訊獲取工具,你用過沒?

我電腦的 cpu 是 i3 ,但是得到的 cpu 是 4(應該得到的是2) ,為什麼呢?

cpu_count() 返回的是 cpu 邏輯數量,物理數量得加上引數cpu_count(logical = True ) 執行得到的 cpu 數量為 2,也就是我們常說的雙核四執行緒。

小 demo

如果我們希望得到類似於 top 命令的使用率排行,那我們應該如何做呢?鑑於前面學習的 cpu_percent 我們來嘗試一下:

psutil.cpu_percent(interval=3, percpu=True)
複製程式碼

其中的 interval 代表比較間隔之前和之後經過的系統CPU時間,也就是比較 3 秒間隔中 cpu 的佔用率

Python 系統資源資訊獲取工具,你用過沒?

如果要實現排行,那麼就需要很多的記錄,意味著我們可以嘗試通過 for 迴圈來實現(此處將時間間隔設為 1 即可):

Python 系統資源資訊獲取工具,你用過沒?

當然,這僅僅只是將資訊輸出了 10 次,如果要進行排行,那麼還需要其他的處理。

Python 系統資源資訊獲取工具,你用過沒?

上圖是我電腦的資源資訊截圖,結合截圖來看,我們通過程式碼獲取的系統資源資訊還是比較可信的

關於 cpu 資訊獲取的其他知識,請翻閱 psutil 官方文件的 cpu 部分,接下來要學習記憶體的資訊獲取了。

記憶體資訊獲取

virtual_memory()將有關係統記憶體使用情況的統計資訊作為命名元組返回,包括以位元組表示的以下欄位。主要指標:

總計:總實體記憶體。
可用:可以在沒有系統進入交換的情況下立即提供給程式的記憶體。這是通過根據平臺對不同的記憶體值求和來計算的,並且它應該用於以跨平臺方式監視實際記憶體使用情況。
其他指標:

used:使用的記憶體,根據平臺的不同計算,僅供參考。總計 - 免費不一定匹配使用。
free:記憶體不被使用(歸零),隨時可用; 請注意,這並不反映可用的實際記憶體( 請改用)。總計 - 使用不一定與免費匹配 。
active (UNIX):當前正在使用或最近使用的記憶體,因此它在RAM中。
inactive (UNIX):標記為未使用的記憶體。
buffers (Linux,BSD):快取檔案系統後設資料之類的東西。
cached (Linux,BSD):快取各種事物。
shared (Linux,BSD):可由多個程式同時訪問的記憶體。
slab (Linux):核心資料結構快取。
wired (BSD,macOS):標記為始終保留在RAM中的記憶體。它永遠不會移動到磁碟。
複製程式碼

當然,我們並不會關注太細緻的記憶體資訊,只需要獲取內容總量、當前可用量或者當前已用量等資訊即可。

記憶體不足警報的小 demo

現在有這麼一個需求,當監控到記憶體不足 300M 的時候通過程式碼發出警告資訊,我們可以將需求簡化為:記憶體不足、發出提示

Python 系統資源資訊獲取工具,你用過沒?

當然,上面的程式碼並不能夠真正的給我們發出警告,因為它只是向你表達它能夠做到的事。如果需要做到監控,還需要編寫更多的程式碼、設計更好的處理邏輯。

記憶體資訊獲取的其他模組介紹

swap_memory() 將系統交換記憶體統計資訊作為命名元組返回:

total:總交換記憶體(以位元組為單位)
used:以位元組為單位使用的swap記憶體
free:以位元組為單位的自由交換記憶體
percent:計算的百分比使用率(total - available) / total * 100
sin:系統從磁碟交換的位元組數(累計)
sout:系統從磁碟換出的位元組數(累計)
複製程式碼

不過正常狀態下,我們用得並不多,因為它並不是返回系統所有的記憶體資源資訊,而是交換記憶體的統計資訊。

程式資訊

程式資訊文件定位,程式資訊也是我們比較關注的方面,psutil.pids() 可以返回當前執行的PID列表,例如:

>>> psutil.pids()
[1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, ..., 32498]
複製程式碼

文件中有一個比較有意思的介紹

Python 系統資源資訊獲取工具,你用過沒?

我們可以按名稱過濾程式資訊,為什麼說他有意思呢?

比如我們可以通過記錄 Python 的程式資訊、記憶體資源資訊、cpu 資源資訊,來分析我們所寫的 Python 程式碼在伺服器上的資源佔用情況。我們嘗試篩選出 Python 相關的 pid:

>>> [p.info for p in psutil.process_iter(attrs=['pid', 'name']) if 'python' in p.info['name']]

[{'name': 'python3.6', 'pid': 1447}]
>>> 
複製程式碼

pid 1447 的這個程式,正好是我在控制檯中演示程式碼時,啟動的 Python 程式。

總結

好了,關於 psutil 的簡單介紹就到這裡,感覺好像沒有學到什麼高大上的知識?感覺輕輕略過了一遍,並沒有留下什麼深刻映像?

因為作者也是這麼認為的,但是這並不妨礙我們腦中的騷思路

可能下一回,我們就會通過 psutil 實現一個伺服器資源監控和比對的工具,比如這樣的:

Python 系統資源資訊獲取工具,你用過沒?

有可能很完善,但是也有可能不需要那麼多功能。

學習更多 Python、爬蟲以及深度學習相關的知識,可以關注微信公眾號【進擊的Coder】,和大佬一起 Coding 共同進步。

請在評論區為 麵筋哥-程書林打 call

相關文章