用python進行服務器的監控
在linux服務器中,一切皆為文件,就是說,服務器運行的個中信息,其實是可以從某些文件中查詢得到的;百度后,你會知道,在Linux系統中,有一個/proc的虛擬文件系統:
Linux 系統為管理員提供了非常好的方法,使其可以在系統運行時更改內核,而不需要重新引導內核系統,這是通過/proc 虛擬文件系統實現的。/proc 文件虛擬系統是一種內核和內核模塊用來向進程(process)發送信息的機制(所以叫做“/proc”),這個偽文件系統允許與內核內部數據結構交互,獲取有關進程的有用信息,在運行中(on the fly)改變設置(通過改變內核參數)。與其他文件系統不同,/proc 存在於內存而不是硬盤中。proc 文件系統提供的信息如下:
- 進程信息:系統中的任何一個進程,在 proc 的子目錄中都有一個同名的進程 ID,可以找到 cmdline、mem、root、stat、statm,以及 status。某些信息只有超級用戶可見,例如進程根目錄。每一個單獨含有現有進程信息的進程有一些可用的專門鏈接,系統中的任何一個進程都有一個單獨的自鏈接指向進程信息,其用處就是從進程中獲取命令行信息。
- 系統信息:如果需要了解整個系統信息中也可以從/proc/stat 中獲得,其中包括 CPU 占用情況、磁盤空間、內存對換、中斷等
- CPU 信息:利用/proc/CPUinfo 文件可以獲得中央處理器的當前准確信息
- 負載信息:/proc/loadavg 文件包含系統負載信息
- 系統內存信息:/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]