别让服务器死给你看!Python监控/proc,一招揪出所有隐患
使用进行服务器监控
在Linux服务器里, 所有的一切都是文件, 也就是讲, 服务器运行时的各类信息, 实际上是能够从某些文件当中查询获取到的。
Linux系统中,有一个/proc的虚拟文件系统
Linux系统给管理员给出了相当不错的办法, 能让其于系统运行之际去更改内核, 且无需再度引导内核系统, 此靠的是/proc虚拟文件系统加以达成。/proc文件虚拟系统是一种内核以及内核模块用以给进程发送信息的机制, 因此称作“/proc”, 这个伪文件系统准许跟内核内部数据结构展开交互, 获取和进程相关的有益信息, 在运行过程中通过改变内核参数来变更设置。和别的文件系统不一样, /proc处在内存里并非硬件驱动器里面, proc文件系统给出的信息是这些:
1.进程信息方面, 系统里的任意一个进程, 在proc的子目录当中, 都存在一个与之同名的进程ID, 能找到、mem根目录、跟root、stat、statm还有。部分信息唯有超级用户方可看见, 比如说进程根目录。针对每一个单独呈现现有进程信息的进程, 存在一些可供使用的专门链接, 系统中的任何一个进程, 都具备一个单独的自链接专门指向某进程对应的进程信息, 其用途是从进程那里取得命令行信息。
2.想要了解整个系统信息能够从/proc/stat中获取, 这里面涵盖了CPU占用状况, 磁盘空间情况, 内存对换情形以及中断情况等, 若有这般需求。
3.中央处理器的当前准确信息, 可通过利用 /proc/ 文件这种方式得以获得它为CPU信息。 句号为标点符号。
4.负载信息:/proc/ 文件包含系统负载信息
5.系统内存方面的信息是, /proc/ 文件当中涵盖着体现系统内存详细情况的内容, 内存详情里有具体说明物理内存数量的部分, 还有展示可用交换空间数量以及呈现空闲内存数量等情况的部分。
/proc 目录中的主要文件的说明

上面列举了这么多, 是不是看上去让人眼睛花乱, 不过别着急, 实际上我们开展服务器监控, 通常只会频繁用到其中较少的一部分。
利用/proc文件系统进行服务器监控
此前我们清楚了服务器信息能够从何处获取, 那么接下来, 我们所要做的便是编写脚本, 去读取存有我们欲获取其信息的文件, 进而从中获取服务器的运行数据。以下这些是咱们时常会需求监控的服务器的部分数据:
读取/proc/获取内存信息
该文件内容如下
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/获取CPU负载信息
该文件内容如下:
0.00 0.01 0.05 1/128 9424
简要地去说明一下, 关于每个字段所具有的含义, 前面的那三个参数, 它们分别是, 在1分钟内cpu的平均负载, 以及5分钟内cpu的平均负载, 还有15分钟内cpu的平均负载, 而第四个参数, 它是指正在运行的进程数量, 以及总进程数量, 最后一个, 则是代表着最近活跃的进程ID。
下面为实现的监控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
利用的os包获取硬盘信息
import os ''' os.statvfs方法用于返回包含文件描述符fd的文件的文件系统的信息。 语法:os.statvfs([path]) 返回值 f_bsize: 文件系统块大小 f_frsize: 分栈大小 f_blocks: 文件系统数据块总数 f_bfree: 可用块数 f_bavail:非超级用户可获取的块数 f_files: 文件结点总数 f_ffree: 可用文件结点数 f_favail: 非超级用户的可用文件结点数 f_fsid: 文件系统标识 ID f_flag: 挂载标记 f_namemax: 最大文件长度 ''' def disk_stat(): 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
在某一个服务器之上, 或许存在着多块网卡, 于获取网卡信息之际, 你得去传入网卡的名字, 究竟有哪些网卡呢, 能够运用命令去查看。
""" 获取当前服务器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 文件里提取出这些信息, 文件的内容将会是如此这般的:
下面将获取每个网卡的进出流量信息:
#!/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)
最后在提供一个服务的监控脚本
#!/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]
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)