自动化运维-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'):获取当前网络连接信息。返回一个列表。
//获取网卡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

#                                                                                                                        #
posted @ 2022-11-07 17:27  麦恒  阅读(90)  评论(0编辑  收藏  举报