python實現系統公網和私網流量監控

目前很多公司業務已經上雲,使用了大量的雲主機。當前大多數雲廠商的雲主機公網都是採用的eip,也就是內網和外網使用的同一張網卡,所以流量全部經過的同一個網卡。然而這就面臨一個問題,如何將公網和私網的流量分開統計呢?特別是當機器流量異常的時候,如何快速的判斷流量是來自公網還是私網。當然雲廠商一般也提供了eip的監控,然而很多公司也有一套自己的監控,對於自建監控如何實現,這就值得思考了。
本文將採用python實現雲主機的公網和私網流量分開統計,可以將結果輸入到自建監控中,當發生業務故障時,可以快速定位問題。

1. iftop

iftop是linux系統下面一個監控主機與外部通信的工具,它可以實時監控本機與外部機器的流量大小,需要自行下載安裝包編譯安裝。iftop類似與linux系統自帶的top命令,在屏幕終端動態輸出監控結果。同時,iftop支持很多參數可選項,其中-t 參數使用不帶ncurses的文本界面,可以實現將結果保存到文件。

2. os.popen函數

os是python的系統模塊,os.popen可以調用系統的shell命令,相當於直接在shell終端執行shell命令。

3. 實現思路

使用python的os.open來調用iftop命令獲取到和主機通信的所有ip的流量大小。然後分別分析公網和私網的流量,將各自的流量之和統計起來,從而實現分別監控系統的公網和私網流量。

4. 代碼實現

# -*- coding:utf-8 -*-
"""
@Author: Rainbowhhy
@Date: 2020-11-14 15:16:18
"""

import os, re

def is_public_ip(ip):
    # 判斷ip是公網還是私網
    private = re.findall(
        r'^((192\.168)|(198\.18)|(198\.19)|(10\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d))|(172\.(1[6-9]|2[0-9]|3[0-1])))\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$',
        ip)
    if private:
        return 0
    else:
        return 1

def convert_unit(unit):
    # 統一轉換成bit後計算
    if "Gb" in unit:
        flow = float(unit.strip("Gb")) * 1024 * 1024 * 1024
    elif "Mb" in unit:
        flow = float(unit.strip("Mb")) * 1024 * 1024
    elif "Kb" in unit:
        flow = float(unit.strip("Kb")) * 1024
    else:
        flow = float(unit.strip("b"))
    return flow

def get_traffic():
    # 調用iftop命名獲取公網和私網流量
    iftop_info = os.popen("iftop -t -N -n -s 4 2>/dev/null | grep -A 1 -E '^   [0-9]'").read()
    iftop_list = iftop_info.split("\n")
    count = len(iftop_list) - 1
    public_traffic_send = 0
    public_traffic_recv = 0
    private_traffic_send = 0
    private_traffic_recv = 0
    public_ips = []
    private_ips = []
    for i in range(int(count / 2)):
        # 獲取出向流量信息
        traffic_send = iftop_list[i * 2]
        traffic_send_lists = traffic_send.split(" ")
        while "" in traffic_send_lists:
            traffic_send_lists.remove("")
        traffic_send = traffic_send_lists[3]
        traffic_send_float = convert_unit(traffic_send)

        # 獲取入向流量信息
        traffic_recv = iftop_list[i * 2 + 1]
        traffic_recv_lists = traffic_recv.split(" ")
        while "" in traffic_recv_lists:
            traffic_recv_lists.remove("")
        ip = traffic_recv_lists[0]
        traffic_recv = traffic_recv_lists[2]
        traffic_recv_float = convert_unit(traffic_recv)

        # 計算公網和私網的總流量
        if is_public_ip(ip):
            public_ips.append(ip)
            public_traffic_send += traffic_send_float
            public_traffic_recv += traffic_recv_float

        else:
            private_ips.append(ip)
            private_traffic_send += traffic_send_float
            private_traffic_recv += traffic_recv_float
    return public_traffic_send, public_traffic_recv, private_traffic_send, private_traffic_recv

if __name__ == '__main__':
    public_traffic_send, public_traffic_recv, private_traffic_send, private_traffic_recv = get_traffic()
    print("公網入向:%s" % public_traffic_recv)
    print("公網出向:%s" % public_traffic_send)
    print("私網入向:%s" % private_traffic_recv)
    print("私網出向:%s" % private_traffic_send)

5. 輸出結果截圖

如下圖是輸出結果展示
file:///home/rainbowhhy/%E6%A1%8C%E9%9D%A2/monitor.pngpython實現系統公網和私網流量監控

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章