自动化运维-python02-业务服务监控
- 业务服务监控是运维体系中最重要的环节,是保证业务服务质量的关键手段。如何更有效地实现业务服务,是每个运维人员应该思考的问题,不同业务场景需定制不同的监控策略。
- Python在监控方面提供了大量的第三方工具,可以帮助我们快速、有效地开发企业级服务监控平台,为我们的业务保驾护航。
- 例如文件与目录差异对比方法、HTTP质量监控、邮件告警等内容。
1、文件内容差异对比
- difflib模块可以实现文件内容差异对比。
- difflib模块是Python的标准库模块,无需安装(Python 2.3或更高版本默认自带difflib模块,无需额外安装),作用是对比文本之间的差异,且支持输出可读性比较强的HTML文档,与Linux下的diff命令相似。
- 可以使用difflib对比代码、配置文件的差别,在版本控制方面是非常有用。
1.1、对比两个字符串
- 使用difflib模块实现两个字符串的差异对比。
]# cat test.py #!/usr/bin/env python3 import difflib text1 = """text1: #定义字符串1 This module provides classes and functions for comparing sequences. including HTML and context and unified diffs. difflib document v7.4 add string """ text1_lines = text1.splitlines() #以行进行分隔,以便进行对比 text2 = """text2: #定义字符串2 This module provides classes and functions for Comparing sequences. including HTML and context and unified diffs. difflib document v7.5""" text2_lines = text2.splitlines() #以行进行分隔,以便进行对比 d = difflib.Differ() #创建Differ()对象 diff = d.compare(text1_lines, text2_lines) # 采用compare方法对字符串进行比较 print('\n'.join(list(diff)))
- 运行代码,结果是:
]# python3 test.py - text1: #定义字符串1 ? ^ ^ + text2: #定义字符串2 ? ^ ^ - This module provides classes and functions for comparing sequences. ? ^ + This module provides classes and functions for Comparing sequences. ? ^ including HTML and context and unified diffs. - difflib document v7.4 ? ^ + difflib document v7.5 ? ^ - add string
- 符号含义说明
1.2、对比两个字符串,结果输出为HTML格式
- 使用difflib模块实现两个字符串的差异对比,将比较结果输出为HTML格式。
//将上面示例中的 d = difflib.Differ() diff = d.compare(text1_lines, text2_lines) print('\n'.join(list(diff))) //替换成 d = difflib.HtmlDiff() #创建HtmlDiff()类对象 print(d.make_file(text1_lines, text2_lines)) #通过make_file方法输出HTML格式的比对结果
- 运行代码
]# python3 test.py > diff.html
- 在浏览器中打开diff.html文件
1.3、对比两个文件
- 两个文件内容
]# cat text1.txt This module provides classes and functions for comparing sequences. including HTML and context and unified diffs. difflib document v7.4 add string ]# cat text2.txt This module provides classes and functions for Comparing sequences. including HTML and context and unified diffs. difflib document v7.5
- 使用difflib模块实现两个文件的差异对比
]# cat test.py #!/usr/bin/python import difflib import sys try: textfile1=sys.argv[1] #第一个配置文件路径参数 textfile2=sys.argv[2] #第二个配置文件路径参数 except Exception as e: print("Error:"+str(e)) print("Usage:test.py filename1 filename2") sys.exit() with open(textfile1 ,encoding='utf-8') as f: f1 = f.readlines() with open(textfile2,encoding='utf-8') as f: f2 = f.readlines() d = difflib.Differ() #创建Differ()对象 diff = d.compare(f1, f2) # 采用compare方法对字符串进行比较 print('\n'.join(list(diff)))
- 运行代码
]# python3 test.py text1.txt text2.txt
2、文件,目录差异对比
- filecmp模块是Python的标准库模块,无需安装(Python 2.3或更高版本默认自带difflib模块,无需额外安装)。
- filecmp可以实现文件、目录、遍历子目录的差异对比功能。比如报告中输出目标目录比原始多出的文件或子目录,即使文件同名也会判断是否为同一个文件(内容级对比)等。
- filecmp提供三个方法,分别为cmp(单文件对比)、cmpfiles(多文件对比)、dircmp(目录对比)
2.1、单文件对比
- 单文件对比:采用filecmp.cmp(f1,f2[,shallow])方法,比较文件名为f1和f2的文件,相同返回True,不相同返回False。
- shallow默认为True,意思是只根据os.stat()方法返回的文件基本信息进行对比,比如最后访问时间、修改时间、状态改变时间等,会忽略文件内容的对比。
- 当shallow为False时,则os.stat()与文件内容同时进行校验。
>>> import filecmp >>> filecmp.cmp("/root/passwd1","/root/passwd2") True >>> filecmp.cmp("/root/passwd1","/root/passwd3") False
2.2、多文件对比
- 多文件对比:采用filecmp.cmpfiles(dir1,dir2,common[,shallow])方法,对比dir1与dir2目录给定的文件清单。该方法返回文件名的三个列表,分别为匹配、不匹配、错误。
- 匹配列表,包含文件内容一致的文件。
- 不匹配列表,包含文件内容不一致的文件。
- 错误列表包括了目录不存在文件、不具备读权限或其他原因导致的不能比较的文件清单。
- 两个目录的文件清单
]# md5sum yum1/* 9098fc723b1e00c92e8515f06980d83e yum1/CentOS-Base.repo b5e6145ee190059114d3d1cdfb351968 yum1/docker-ce.repo bec6648ba75ea3c9bcb93c048e7a087e yum1/epel.repo ]# md5sum yum2/* 9098fc723b1e00c92e8515f06980d83e yum2/CentOS-Base.repo 39a04b86e4c17425acf6df3f6c55e645 yum2/docker-ce.repo
- 对比多个文件
>>> import filecmp //CentOS-Base.repo文件内容一样,docker-ce.repo文件内容不一样,epel.repo文件在yum2目录中不存在 >>> filecmp.cmpfiles("/root/test/yum1","/root/test/yum2",['CentOS-Base.repo','epel.repo','docker-ce.repo']) (['CentOS-Base.repo'], ['docker-ce.repo'], ['epel.repo'])
2.3、目录对比
- 目录对比:通过dircmp(a, b[, ignore[, hide]])类创建一个目录比较对象,其中a和b是参加比较的目录名。dircmp类可以获得目录比较的详细信息,如只有在a目录中包括的文件、a与b都存在的子目录、匹配的文件等,同时支持递归。
- ignore代表文件名忽略的列表,并默认为['RCS','CVS','tags']。
- hide代表隐藏的列表,默认为[os.curdir,os.pardir]。
- dircmp提供三个方法:
- report():比较当前指定目录中的内容;
- report_partial_closure():比较当前指定目录及第一级子目录中的内容;
- report_full_closure():递归比较所有指定目录的内容。
- dircmp类的属性:
- left:左目录,如类定义中的a;
- right:右目录,如类定义中的b;
- left_list:左目录中的文件及目录列表;
- right_list:右目录中的文件及目录列表;
- common:两边目录共同存在的文件或目录;
- left_only:只在左目录中的文件或目录;
- right_only:只在右目录中的文件或目录;
- common_dirs:两边目录都存在的子目录;
- common_files:两边目录都存在的子文件;
- common_funny:两边目录都存在的子目录(不同目录类型或os.stat()记录的错误);
- same_files:匹配相同的文件;
- diff_files:不匹配的文件;
- funny_files:两边目录中都存在,但无法比较的文件;
- subdirs:将common_dirs目录名映射到新的dircmp对象,格式为字典类型。
]# cat test.py #!/usr/bin/env python3 import filecmp a="/root/test/yum1" #定义左目录 b="/root/test/yum2" #定义右目录 dirobj=filecmp.dircmp(a,b,['test.py']) #目录比较,忽略test.py文件 dirobj.report() dirobj.report_partial_closure() dirobj.report_full_closure() print("left_list:"+ str(dirobj.left_list)) print("right_list:"+ str(dirobj.right_list)) print("common:"+ str(dirobj.common)) print("left_only:"+ str(dirobj.left_only)) print("right_only:"+ str(dirobj.right_only)) print("common_dirs:"+ str(dirobj.common_dirs)) print("common_files:"+ str(dirobj.common_files)) print("common_funny:"+ str(dirobj.common_funny)) print("same_file:"+ str(dirobj.same_files)) print("diff_files:"+ str(dirobj.diff_files)) print("funny_files:"+ str(dirobj.funny_files))
3、smtplib模块发送电子邮件
- 电子邮件是最流行的互联网应用之一。在系统管理领域,我们常常使用邮件来发送告警信息、业务质量报表等,方便运维人员第一时间了解业务的服务状态。
- smtplib模块是Python的标准库模块,无需额外安装(Python 2.3或更高版本默认自带smtplib模块)。
- smtplib模块实现邮件的发送功能,模拟一个smtp客户端,通过与smtp服务器交互来实现邮件发送的功能。
- SMTP类定义:smtplib.SMTP([host[,port[,local_hostname[,timeout]]]]),作为SMTP的构造函数,功能是与smtp服务器建立连接,在连接成功后,就可以向服务器发送相关请求,比如登录、校验、发送、退出等。
- host为远程smtp主机地址,比如smtp.163.com。
- port为连接端口,默认为25。
- local_hostname的作用是在本地主机的FQDN(完整的域名)发送HELO/EHLO(标识用户身份)指令。
- timeout为连接或尝试在多少秒超时。
- SMTP类具有如下方法:
- SMTP.connect([host[,port]])方法,连接远程smtp主机方法。
- host为远程主机地址,port为远程主机smtp端口,默认25,也可以直接使用host:port形式来表示,例如:SMTP.connect("smtp.163.com","25")。
- SMTP.login(user,password)方法,远程smtp主机的校验方法,参数为用户名与密码,如SMTP.login("python_2014@163.com","sdjkg358")。
- SMTP.sendmail(from_addr,to_addrs,msg[,mail_options,rcpt_options])方法,实现邮件的发送功能,参数依次为是发件人、收件人、邮件内容,例如:SMTP.sendmail("python_2014@163.com","demo@domail.com",body),其中body内容定义如下:
- SMTP.starttls([keyfile[,certfile]])方法,启用TLS(安全传输)模式,所有SMTP指令都将加密传输,例如使用gmail的smtp服务时需要启动此项才能正常发送邮件,如SMTP.starttls()。
- SMTP.quit()方法,断开smtp服务器的连接。
- SMTP.connect([host[,port]])方法,连接远程smtp主机方法。
1
# #