網絡監控的工具很多,但沒有找到精確到毫秒/微秒級別的,於是自己做了一個。這個工具可以查看/調試網絡活動的內部細節,比如網絡流量的波動,多網卡網絡活動的時序。最快可以精確到0.4ms的採樣周期。
比如下圖是一次下載開始時的網絡活動細節。
圖:一次下載開始時的網絡活動
原理
在Linux下,統計網絡活動的工具有很多。比如:最常用的ifconfig 就可以顯示指定接口的收/發的數據(字節數和包的數目),以及丟包數,錯誤數等。
類似的工具還有:
ip -s link:側重於接口的統計netstat -s:側重於協議的統計ethtool -S:也是接接口統計
當然,proc文件系統裡也有,甚至中斷的統計值也有:
/proc/net/dev/proc/softirqs: 包括網絡收發相關的中斷計數
用下面的命令,就可以用「實時的」方式查看網絡收發數據的狀況了。當然,不是那麼直觀。
watch -n 0.1 cat "/proc/net/dev | grep enp"
為了達到最快的速度,我們需要使用源頭的數據。
源頭在 /sys/class/net/(nic)/statistics 目錄,因為這個目錄裡的文件是單一的,一個文件對應於一個計數項。
圖:網絡狀態計數器
現在我們可以用 watch 假裝實時地觀察感興趣的計數器了。
/sys/class/net/enp1s0/statistics$ watch -n 0.1 cat rx_bytes tx_bytes
實現及特性
對上面的計數器定時採樣,就可以得到網絡活動的波動。主要有下面一些選項:
採樣周期採樣總時長觸發條件:什麼情況下開始採樣網絡接口:對哪些網絡接口進行採樣計數器:對哪些計數器進行採樣,比如收到的字節數,發送的包的數目等
下面是這個工具的命令行選項及運行示意。
圖:netmon命令行使用及示例
數據輸出為CSV文件。為了方便,時間戳已使用相對時間(以採樣開始作為時間0點),數據也使用相對值(即每個周期的數據增量)。
輸出的CSV文件可以用Excel顯示為圖表。為了方便,用pandas寫了幾行腳本生成圖表,在python notebook裡運行。
圖:多網卡監控示例
最後的圖表也可以用累加方式顯示。看哪種更直觀。
圖:監控數據累加顯示
性能
最初是用Python寫的採樣程序,採樣周期只能到大約2ms,如果採樣的計數器較多,可能只能到20ms.
最後還是改用C++,採樣周期可以到20μs. 但是,作業系統對計數器的更新頻率遠沒有這麼高,估計是400μs的樣子。也許內核裡可以設置這個更新頻率?沒有深究,因為0.4ms的採樣周期已經足夠用了。
觸發
因為不可能無限地採樣,所以什麼時候開始採樣,是比較重要的一個環節。模仿示波器的思路,增加了對觸發條件的支持。
觸發的條件是:當採樣的數據超過某個閾值才開始採樣。比如採樣的計數器是 rx_bytes, 閾值是 8000, 採樣周期是1ms,則表示:在1ms內收到的數據超過8000位元組,即開始採樣。
對於多網卡/多計數器,則有一個聚合函數來處理這些計數器:
min: 表示所有計數器中最小的值,要超過閾值。其實就是說:所有計數器都要超過閾值,才開始採樣。max: 任一計數器超過閾值,即開始採樣。avg: 計數器的平均值超過閾值,即開始採樣。sum: 計數器的總和超過閾值,即開始採樣。first/last: 按照命令行中的輸入順序,第一個/最後一個計數器超過閾值,開始採樣。
結語
在Linux系統中,/sys/class/net/(nic)/statistics 目錄包含了各種網絡狀態的計數器。對它們進行採樣,可以實現毫秒級的網絡監控,可用於診斷/調優網絡活動細節及時序。
這個工具實現了命令行下的採樣,包含多種觸發採樣條件,最高有效採樣周期達0.4ms(受限於作業系統的網絡狀態更新頻率)。另外提供了腳本對數據進行可視化。總體上相當於一個簡易的「網絡示波器」。
代碼:https://github.com/loblab/netmon