自动化运维-python01-系统基础信息模块
- 系统基础信息采集模块作为监控模块的重要组成部分,能够帮助运维人员了解当前系统的健康程度,同时也是衡量业务的服务质量的依据,比如系统资源吃紧,会直接影响业务的服务质量及用户体验,另外获取设备的流量信息,也可以让运维人员更好地评估带宽、设备资源是否应该扩容。
- 可以通过Python第三方系统基础模块轻松获取服务关键运营指标数据,包括Linux基本性能、块设备、网卡接口、系统信息、网络地址库等信息。在采集到这些数据后,我们就可以全方位了解系统服务的状态,再结合告警机制,可以在第一时间响应,将异常出现在苗头时就得以处理。
1、系统性能信息模块psutil
- 模块说明参考官网:https://psutil.readthedocs.io/en/latest/
- psutil是一个跨平台库,能够轻松实现获取系统运行的进程和系统利用率(包括CPU、内存、磁盘、网络等)信息。
- 它主要应用于系统监控,分析和限制系统资源及进程的管理。
- 它实现了同等命令行工具提供的功能,如ps、top、lsof、netstat、ifconfig、who、df、kill、free、nice、ionice、iostat、iotop、uptime、pidof、tty、taskset、pmap等。
- psutil大小单位一般都采用字节。
1.1、安装psutil模块
1、安装python3
]# yum install python3
2、安装psutil模块
]# pip3 install psutil
- 安装时报错:
- 报错信息:
- 编译中断。
- error: command 'gcc' failed with exit status 1
- 解决问题:
- 只需要安装python编译环境即可。
- 报错信息:
]# yum install python3-devel
psutil模块的类和函数
1.2、获取CPU信息
- Linux操作系统的CPU利用率有以下几个部分:
- User Time:执行用户进程的时间百分比。
- System Time:执行内核进程和中断的时间百分比。
- Wait IO:由于IO等待而使CPU处于idle(空闲)状态的时间百分比。
- Idle:CPU处于idle状态的时间百分比。
- CPU相关的函数:
- psutil.cpu_times(percpu=False)获取CPU的完整信息
- psutil.cpu_count(logical=True)获取CPU的个数
- psutil.getloadavg()获取CPU的平均负载
- psutil.cpu_percent(interval=None, percpu=False):返回CPU的使用率
- psutil.cpu_stats()获取CPU的统计信息,包括上下文切换、中断、软中断和系统调用次数。
- psutil.cpu_freq(percpu=False)获取CPU频率
- psutil.cpu_times_percent(interval=None, percpu=False)获取耗时百分比
- 获取CPU相关的信息
>>> import psutil //查看CUP时间相关的信息(单位是秒) >>> psutil.cpu_times() scputimes(user=5.51, nice=0.0, system=9.42, idle=86.06, iowait=0.14, irq=0.0, softirq=0.19, steal=0.0, guest=0.0, guest_nice=0.0) //查看逻辑CUP时间相关的信息 >>> psutil.cpu_times(percpu=True) [scputimes(user=2.38, nice=0.0, system=5.0, idle=52.12, iowait=0.08, irq=0.0, softirq=0.18, steal=0.0, guest=0.0, guest_nice=0.0), scputimes(user=3.67, nice=0.0, system=5.07, idle=51.22, iowait=0.06, irq=0.0, softirq=0.03, steal=0.0, guest=0.0, guest_nice=0.0)] //时间百分比,默认percpu=False >>> psutil.cpu_times_percent() scputimes(user=4.3, nice=0.0, system=4.1, idle=91.2, iowait=0.0, irq=0.0, softirq=0.3, steal=0.0, guest=0.0, guest_nice=0.0) //获取CPU的逻辑个数,默认logical=True >>> psutil.cpu_count() 2 //获取CPU的物理个数 >>> psutil.cpu_count(logical=False) 2 //1分钟、5分钟、15分钟的平均负载 >>> psutil.getloadavg() (0.26, 0.19, 0.08)
1.3、获取内存信息
- Linux系统的内存利用率信息涉及total(内存总数)、used(已使用的内存数)、free(空闲内存数)、buffers(缓冲使用数)、cache(缓存使用数)、swap(交换分区使用数)等。
- 内存相关的函数:
- psutil.virtual_memory():获取系统内存的信息。返回一个元组,包括总内存、可用内存、内存利用率、buffer和cache等。单位为字节。
- psutil.swap_memory():获取SWAP分区信息。返回一个元组。
>>> import psutil //获取内存信息 >>> psutil.virtual_memory() svmem(total=1907814400, available=744591360, percent=61.0, used=996823040, free=102785024, active=1148567552, inactive=420945920, buffers=1179648, cached=807026688, shared=12111872, slab=132632576) //获取SWAP分区信息 >>> psutil.swap_memory() sswap(total=0, used=0, free=0, percent=0.0, sin=0, sout=0)
1.4、磁盘信息
- 磁盘利用率使用psutil.disk_usage方法获取。
- 磁盘IO信息包括read_count(读IO数)、write_count(写IO数)、read_bytes(IO读字节数)、write_bytes(IO写字节数)、read_time(磁盘读时间)、write_time(磁盘写时间)等,可以使用psutil.disk_io_counters()获取。
- 磁盘相关的函数:
- psutil.disk_partitions(all=False):获取磁盘分区信息。返回一个元组,包含所有已挂载磁盘的磁盘名称、挂载点、文件系统类型等信息。
- psutil.disk_usage(path):获取指定路径所在磁盘的使用情况。返回一个元组,包括磁盘的容量、已经使用的磁盘容量、磁盘的空间利用率等。
- psutil.disk_io_counters(perdisk=False, nowrap=True):获取磁盘的io统计信息。返回一个元组,包括读、写的次数,读、写的字节数等。
- 当perdisk的值为True,则分别列出单个磁盘的统计信息(字典:key为磁盘名称,value为统计的namedtuple)。
>>> import psutil //获取磁盘分区信息 >>> psutil.disk_partitions() [sdiskpart(device='/dev/mapper/centos-root', mountpoint='/', fstype='xfs', opts='rw,relatime,attr2,inode64,noquota', maxfile=255, maxpath=4096), sdiskpart(device='/dev/sda1', mountpoint='/boot', fstype='xfs', opts='rw,relatime,attr2,inode64,noquota', maxfile=255, maxpath=4096)] //获取指定路径所在磁盘的使用情况 >>> psutil.disk_usage("/") sdiskusage(total=18238930944, used=7210045440, free=11028885504, percent=39.5) //使用psutil.disk_io_counters获取硬盘总的IO个数、读写信息 >>> psutil.disk_io_counters() sdiskio(read_count=62817, write_count=792794, read_bytes=3743484928, write_bytes=4617151488, read_time=115609, write_time=253199, read_merged_count=2, write_merged_count=6310, busy_time=149539)
1.5、网络信息
- 使用psutil.net_io_counters()方法获取bytes_sent(发送字节数)、bytes_recv=28220119(接收字节数)、packets_sent=200978(发送数据包数)、packets_recv=212672(接收数据包数)等。
- 网络相关的函数:
- psutil.net_io_counters(pernic=False, nowrap=True):获取网卡io统计信息。包括收发字节数,收发包的数量、出错的情况和删包情况。
- 当pernic为True时,则列出所有网卡的统计信息。
- psutil.net_if_addrs():获取网络接口信息。返回一个字典,包括IP地址和mac地址、子网掩码和广播地址。
- psutil.net_if_stats():获取网络接口状态信息。返回一个字典,包括是否启动、通信类型、传输速度与mtu。
- psutil.net_connections(kind='inet'):获取当前网络连接信息。返回一个列表。
- psutil.net_io_counters(pernic=False, nowrap=True):获取网卡io统计信息。包括收发字节数,收发包的数量、出错的情况和删包情况。
//获取网卡io统计信息 >>> psutil.net_io_counters() snetio(bytes_sent=1860806664, bytes_recv=1632107043, packets_sent=9075082, packets_recv=9020129, errin=0, errout=0, dropin=1, dropout=0) //获取网络接口信息 >>> psutil.net_if_addrs() {'lo': [snicaddr(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_PACKET: 17>, address='00:00:00:00:00:00', netmask=None, broadcast=None, ptp=None)], 'ens33': [snicaddr(family=<AddressFamily.AF_INET: 2>, address='10.1.1.11', netmask='255.255.255.0', broadcast='10.1.1.255', ptp=None), snicaddr(family=<AddressFamily.AF_INET6: 10>, address='fe80::1760:27f7:9b73:8863%ens33', netmask='ffff:ffff:ffff:ffff::', broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_PACKET: 17>, address='00:0c:29:1a:dc:4b', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)], ...} //获取网络接口状态信息 >>> psutil.net_if_stats() {'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536, flags='up,loopback,running'), 'virbr0-nic': snicstats(isup=False, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=10, mtu=1500, flags='broadcast,multicast'), 'ens33': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=1000, mtu=1500, flags='up,broadcast,running,multicast') ...}
1.6、系统进程管理方法
1、进程信息
- 获得当前系统的进程信息,可以让运维人员得知应用程序的运行状态,包括进程的启动时间、查看或设置CPU亲和度、内存使用率、IO信息、socket连接、线程数等,这些信息可以呈现出指定进程是否存活、资源利用情况。
- 进程相关的函数:
- psutil.pids():获取系统全部进程。
- psutil.pid_exists(pid):判断给点定的pid是否存在
- psutil.process_iter(attrs=None, ad_value=None):迭代当前正在运行的进程,返回的是每个进程的Process对象
- psutil.wait_procs(procs, timeout=None, callback=None)
>>> import psutil,datetime //列出所有进程PID >>> psutil.pids() [1, 2, 4, 6, 7, 8, 9, 10, 11, 12, ...] //实例化一个Process对象,参数为一进程PID p = psutil.Process(3573) //进程名 >>> p.name() 'kube-apiserver' //进程bin路径 >>> p.exe() '/usr/local/bin/kube-apiserver' //进程工作目录绝对路径 >>> p.cwd() '/' //进程状态 >>> p.status() 'sleeping' //进程创建时间,时间戳格式 >>> p.create_time() 1667990543.82 >>> datetime.datetime.fromtimestamp(p.create_time()).strftime("%Y-%m-%d %H:%M:%S") '2022-11-09 18:42:23' //进程uid信息 >>> p.uids() puids(real=0, effective=0, saved=0) //进程gid信息 >>> p.gids() pgids(real=0, effective=0, saved=0) //进程CPU时间信息,包括user、system两个CPU时间 >>> p.cpu_times() pcputimes(user=1603.18, system=1095.64, children_user=0.0, children_system=0.0, iowait=0.0) //get进程CPU亲和度,如要设置进程CPU亲和度,将CPU号作为参数即可 >>> p.cpu_affinity() [0, 1] //进程内存利用率 >>> p.memory_percent() 15.987332939724116 //进程内存rss、vms信息 >>> p.memory_info() pmem(rss=305008640, vms=1126350848, shared=22855680, text=58343424, lib=0, data=1008041984, dirty=0) //进程IO信息,包括读写IO数及字节数 >>> p.io_counters() pio(read_count=6910913, write_count=4746569, read_bytes=201392128, write_bytes=0, read_chars=657306808, write_chars=880272895) //返回打开进程socket的namedutples列表,包括fs、family、laddr等信息 >>> p.connections() [pconn(fd=9, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='127.0.0.1', port=44414), raddr=addr(ip='127.0.0.1', port=2379), status='ESTABLISHED'), pconn(fd=33, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='127.0.0.1', port=44464), raddr=addr(ip='127.0.0.1', port=2379), status='ESTABLISHED'), ...] //进程开启的线程数 >>> p.num_threads() 9
2、popen类
- psutil的popen类的作用是获取用户启动的应用程序进程信息,以便跟踪程序进程的运行状态。
>>> import psutil >>> from subprocess import PIPE //通过psutil的Popen方法启动的应用程序,可以跟踪该程序运行的所有相关信息 >>> p = psutil.Popen(["/usr/bin/python", "-c", "print('hello')"], stdout=PIPE) >>> p.name() 'python' >>> p.username() 'root' >>> p.communicate() (b'hello\n', None)
1.7、传感器
>>> import psutil //返回电池状态 >>> psutil.sensors_fans() //返回硬件风扇速度 >>> psutil.sensors_battery() //返回硬件温度 >>> psutil.sensors_temperatures(fahrenheit=False)
1.8、获取登录用户和开机时间
>>> import psutil,datetime //当前登录系统的用户信息 >>> psutil.users() [suser(name='root', terminal='pts/0', host='10.1.1.1', started=1668043776.0, pid=10791)] //获取开机时间(Linux时间戳) >>> psutil.boot_time() 1667990468.0 //转换成自然时间格式 >>> datetime.datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S") '2022-11-09 18:41:08'
2、DNS处理模块dnspython
- dnspython是Python实现的一个DNS工具包,它支持几乎所有的记录类型,可以用于查询、传输并动态更新ZONE信息,同时支持TSIG(事务签名)验证消息和EDNS0(扩展DNS)。
- 在系统管理方面,可以利用其查询功能来实现DNS服务监控以及解析结果的校验,可以代替nslookup及dig等工具,轻松做到与现有平台的整合。
2.1、安装IPy模块
]# pip3 install -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com dnspython
2.2、域名解析方法
- dnspython提供了一个DNS解析器类--resolver,使用它的query方法来实现域名的查询功能。
- query方法的定义如下:
query(self, qname, rdtype=1, rdclass=1, tcp=False, source=None, raise_on_no_answer=True, source_port=0)
- qname参数为查询的域名。
- rdtype参数用来指定RR资源的类型:
- A记录,将主机名转换成IP地址;
- MX记录,邮件交换记录,定义邮件服务器的域名;
- CNAME记录,指别名记录,实现域名间的映射;
- NS记录,标记区域的域名服务器及授权子域;
- PTR记录,反向解析,与A记录相反,将IP转换成主机名;
- SOA记录,SOA标记,一个起始授权区的定义。
- rdclass参数用于指定网络类型,可选的值有IN、CH与HS,其中IN为默认,使用最广泛。
- tcp参数用于指定查询是否启用TCP协议,默认为False(不启用)。
- source与source_port参数作为指定查询源地址与端口,默认值为查询设备IP地址和0。
- raise_on_no_answer参数用于指定当查询无应答时是否触发异常,默认为True。
2.3、解析类型示例
- 常见的DNS解析类型包括A、MX、NS、CNAME等。
- 利用dnspython的dns.resolver.query方法可以简单实现这些DNS类型的查询,为后面要实现的功能提供数据来源,比如对一个使用DNS轮循业务的域名进行可用性监控,需要得到当前的解析结果。
1、A记录
- 实现查询A记录的方法:
]# cat test.py #!/usr/bin/env python3 import dns.resolver domain = input('Please input an domain:') #输入域名地址 A = dns.resolver.query(domain, 'A') #指定查询类型为A记录 for i in A.response.answer: #通过response.answer方法获取查询回应信息 for j in i.items: #遍历回应信息 print(j.address)
- 以www.google.com域名为例,运行代码
]# python3 test.py Please input an domain:www.baidu.com 36.152.44.96 36.152.44.95
2、MX记录
- 查询MX记录的方法:
]# cat test.py #!/usr/bin/env python3 import dns.resolver domain = input('Please input an domain:') #输入域名地址 MX = dns.resolver.query(domain, 'MX') #指定查询类型为MX记录 for i in MX: #遍历回应结果,输出MX记录的preference及exchanger信息 print('MX preference =', i.preference, 'mail exchanger =', i.exchange)
- 以163.com域名为例,运行代码
]# python3 test.py Please input an domain:163.com MX preference = 10 mail exchanger = 163mx02.mxmail.netease.com. MX preference = 50 mail exchanger = 163mx00.mxmail.netease.com. MX preference = 10 mail exchanger = 163mx01.mxmail.netease.com. MX preference = 10 mail exchanger = 163mx03.mxmail.netease.com.
3、NS记录
- 查询NS记录的方法:
]# cat test.py #!/usr/bin/env python3 import dns.resolver domain = input('Please input an domain:') #输入域名地址 NS = dns.resolver.query(domain, 'NS') #指定查询类型为NS记录 for i in NS.response.answer: #通过response.answer方法获取查询回应信息 for j in i.items: #遍历回应信息 print(j.to_text())
- 以baidu.com域名为例,运行代码(如果输入二级或多级域名,如www.baidu.com,则是错误的)
]# python3 test.py Please input an domain:baidu.com ns3.baidu.com. ns2.baidu.com. ns4.baidu.com. dns.baidu.com. ns7.baidu.com.
4、CNAME记录
- 查询CNAME记录的方法
]# cat test.py #!/usr/bin/env python3 import dns.resolver domain = input('Please input an domain:') #输入域名地址 CNAME = dns.resolver.query(domain, 'CNAME') #指定查询类型为CNAME记录 for i in CNAME.response.answer: #通过response.answer方法获取查询回应信息 for j in i.items: #遍历回应信息 print(j.to_text())
- 以www.baidu.com域名为例,运行代码
]# python3 test.py Please input an domain:www.baidu.com www.a.shifen.com.
1
# #