1. 程式人生 > >用python進行服務器的監控

用python進行服務器的監控

網絡協議 硬盤信息 以及 4.0 簡單 frs 偽文件系統 apache star

用python進行服務器的監控

在linux服務器中,一切皆為文件,就是說,服務器運行的個中信息,其實是可以從某些文件中查詢得到的;百度後,你會知道,在Linux系統中,有一個/proc的虛擬文件系統:

Linux 系統為管理員提供了非常好的方法,使其可以在系統運行時更改內核,而不需要重新引導內核系統,這是通過/proc 虛擬文件系統實現的。/proc 文件虛擬系統是一種內核和內核模塊用來向進程(process)發送信息的機制(所以叫做“/proc”),這個偽文件系統允許與內核內部數據結構交互,獲取有關進程的有用信息,在運行中(on the fly)改變設置(通過改變內核參數)。與其他文件系統不同,/proc 存在於內存而不是硬盤中。proc 文件系統提供的信息如下:

  1. 進程信息:系統中的任何一個進程,在 proc 的子目錄中都有一個同名的進程 ID,可以找到 cmdline、mem、root、stat、statm,以及 status。某些信息只有超級用戶可見,例如進程根目錄。每一個單獨含有現有進程信息的進程有一些可用的專門鏈接,系統中的任何一個進程都有一個單獨的自鏈接指向進程信息,其用處就是從進程中獲取命令行信息。
  2. 系統信息:如果需要了解整個系統信息中也可以從/proc/stat 中獲得,其中包括 CPU 占用情況、磁盤空間、內存對換、中斷等
  3. CPU 信息:利用/proc/CPUinfo 文件可以獲得中央處理器的當前準確信息
  4. 負載信息:/proc/loadavg 文件包含系統負載信息
  5. 系統內存信息:/proc/meminfo 文件包含系統內存的詳細信息,其中顯示物理內存的數量、可用交換空間的數量,以及空閑內存的數量等

/proc 目錄中的主要文件的說明

文件或目錄名稱說明
apm 高級電源管理信息
cmdline 這個文件給出了內核啟動的命令行
CPUinfo 中央處理器信息
devices 可以用到的設備(塊設備/字符設備)
dma 顯示當前使用的 DMA 通道
filesystems 核心配置的文件系統
ioports 當前使用的 I/O 端口
interrupts 這個文件的每一行都有一個保留的中斷
kcore 系統物理內存映像
kmsg 核心輸出的消息,被送到日誌文件
mdstat 這個文件包含了由 md 設備驅動程序控制的 RAID 設備信息
loadavg 系統平均負載均衡
meminfo 存儲器使用信息,包括物理內存和交換內存
modules 這個文件給出可加載內核模塊的信息
lsmod 程序用這些信息顯示有關模塊的名稱,大小,使用數目方面的信息
net 網絡協議狀態信息
partitions 系統識別的分區表
pci pci 設備信息
scsi scsi 設備信息
self 到查看/proc 程序進程目錄的符號連接
stat 這個文件包含的信息有 CPU 利用率,磁盤,內存頁,內存對換,全部
swaps 顯示的是交換分區的使用情況
uptime 這個文件給出自從上次系統自舉以來的秒數,以及其中有多少秒處於空閑
version 這個文件只有一行內容,說明正在運行的內核版本。可以用標準的編程方法進行分析獲得所需的系統信息

以上列出來了這麽多,是不是看起來眼花繚亂,但是不要慌,其實我們進行服務器監控,只會經常用到其中比較少的以部門。

利用/proc文件系統進行服務器監控

以上我們知道了服務器信息可以從哪裏獲取,那麽下面,我們就是編寫腳本,讀取我們要獲取信息的文件,從中得到服務器的運行數據。下面是我們經常會需要監控的服務器的一些數據:

讀取/proc/meminfo獲取內存信息

該文件內容如下

MemTotal: 1017544 kB
MemFree: 583304 kB
MemAvailable: 756636 kB
Buffers: 42996 kB
Cached: 238820 kB
SwapCached: 0 kB
Active: 116092 kB
Inactive: 252004 kB
Active(anon): 11956 kB
Inactive(anon): 85136 kB
Active(file): 104136 kB
Inactive(file): 166868 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 1044476 kB
SwapFree: 1044272 kB
Dirty: 64 kB
Writeback: 0 kB
AnonPages: 86304 kB
Mapped: 48832 kB
Shmem: 10812 kB
Slab: 40648 kB
SReclaimable: 29904 kB
SUnreclaim: 10744 kB
KernelStack: 2048 kB
PageTables: 8232 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 1553248 kB
Committed_AS: 681428 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 5796 kB
VmallocChunk: 34359727572 kB
HardwareCorrupted: 0 kB
AnonHugePages: 32768 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 34752 kB
DirectMap2M: 1013760 kB

每個字段具體什麽意思自己百度吧,直接上監控代碼:

""" 內存監控
"""
def memory_stat():
    mem = {}
    f = open(‘/proc/meminfo‘, ‘r‘)
    lines = f.readlines()
    f.close()
    for line in lines:
        if len(line) < 2:
            continue
        name = line.split(‘:‘)[0]
        var = line.split(‘:‘)[1].split()[0]
        mem[name] = float(var)
    mem[‘MemUsed‘] = mem[‘MemTotal‘] - mem[‘MemFree‘] - mem[‘Buffers‘] - mem[‘Cached‘]
    #記錄內存使用率 已使用 總內存和緩存大小
    res = {}
    res[‘percent‘] = int(round(mem[‘MemUsed‘] / mem[‘MemTotal‘] * 100))
    res[‘used‘] = round(mem[‘MemUsed‘] / (1024 * 1024), 2)
    res[‘MemTotal‘] = round(mem[‘MemTotal‘] / (1024 * 1024), 2)
    res[‘Buffers‘] = round(mem[‘Buffers‘] / (1024 * 1024), 2)
    return res

讀取/proc/loadavg獲取CPU負載信息

該文件內容如下:

0.00 0.01 0.05 1/128 9424
簡單說明一下每個字段的含義,前三個參數分別為1、5、15分鐘內cpu的平均負載,第四個參數為正在運行的進程數和總進程數,最後一個代表最近活躍的進程ID

下面為python實現的監控CPU負載的代碼:

""" CPU負載監控
"""
def load_stat():
    loadavg = {}
    f = open("/proc/loadavg")
    con = f.read().split()
    f.close()
    loadavg[‘lavg_1‘]=con[0]
    loadavg[‘lavg_5‘]=con[1]
    loadavg[‘lavg_15‘]=con[2]
    loadavg[‘nr‘]=con[3]


    prosess_list = loadavg[‘nr‘].split(‘/‘)
    loadavg[‘running_prosess‘]=prosess_list[0]
    loadavg[‘total_prosess‘]=prosess_list[1]

    loadavg[‘last_pid‘]=con[4]

    return loadavg

利用python的os包獲取硬盤信息

""" 磁盤空間監控
"""
def disk_stat():
    import os
    hd={}
    disk = os.statvfs(‘/‘)
    hd[‘available‘] = float(disk.f_bsize * disk.f_bavail)
    hd[‘capacity‘] = float(disk.f_bsize * disk.f_blocks)
    hd[‘used‘] = float((disk.f_blocks - disk.f_bfree) * disk.f_frsize)
    res = {}
    res[‘used‘] = round(hd[‘used‘] / (1024 * 1024 * 1024), 2)
    res[‘capacity‘] = round(hd[‘capacity‘] / (1024 * 1024 * 1024), 2)
    res[‘available‘] = res[‘capacity‘] - res[‘used‘]
    res[‘percent‘] = int(round(float(res[‘used‘]) / res[‘capacity‘] * 100))
    return res

獲取服務器的ip

在一個服務器上,可能有多塊網卡, 在獲取網卡信息時,你需要傳入網卡的名字,具體有哪些網卡,可以使用ifconfig命令查看

""" 獲取當前服務器ip
"""
def get_ip(ifname):
    import socket
    import fcntl
    import struct
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(s.fileno(), 0x8915, struct.pack(‘256s‘, ifname[:15]))[20:24])

讀取/proc/net/dev獲取網卡流量信息

我們將會從該文件中獲得系統的網絡接口,以及當系統重啟之後通過它們數據發送和接受數據的信息。 /proc/net/dev文件讓這些信息可用。如果你檢查了這個文件的內容,你就會註意到頭一兩行包含了頭信息等等,這個文件第一列是網絡接口名,第二和第三列顯示了接收和發送的字節數信息(例如總發送字節數,包數,錯誤等等)。這裏我們所感興趣的就是他哦難過不同的網絡設備提取出總發送數據和接收數據。下面的代碼展示了怎麽從/proc/net/dev文件中提取出這些信息,文件內容會是這樣的:

Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
lo:13092608592182 4315193859 0 0 0 0 0 0 13092608592182 4315193859 0 0 0 0 0 0
eth0:6081251983019 4697841969 0 0 0 0 0 0 196939978179 2079619999 0 0 0 0 0 0
eth1:5718927608592 9484371630 0 0 0 0 0 0 142737118022 2007173284 0 0 0 0 0 0

下面將獲取每個網卡的進出流量信息:

#!/usr/bin/env python 
from __future__ import print_function

def net_stat():
    net = {}
    f = open("/proc/net/dev")
    lines = f.readlines()
    f.close
    for line in lines[2:]:
        line = line.split(":")
        eth_name = line[0].strip()
        if eth_name != ‘lo‘:
            net_io = {}
            net_io[‘receive‘] = round(float(line[1].split()[0]) / (1024.0 * 1024.0),2)
            net_io[‘transmit‘] = round(float(line[1].split()[8]) / (1024.0 * 1024.0),2)
            net[eth_name] = net_io
    return net

if __name__ == ‘__main__‘:
    netdevs = net_stat()
    print(netdevs)

最後在提供一個Apache服務的監控腳本

#!/usr/bin/env Python 
import os, sys, time 

while True: 
    time.sleep(4) 
    try: 
        ret = os.popen(‘ps -C apache -o pid,cmd‘).readlines() 
        if len(ret) < 2: 
            print "apache 進程異常退出, 4 秒後重新啟動"
            time.sleep(3) 
            os.system("service apache2 restart") 
    except: 
        print "Error", sys.exc_info()[1]

用python進行服務器的監控