转载请联系新钛云服务公众号。在日常运维中,遇到每天发邮件当天服务器监控状态等类似需求,每天下午快下班的时候还是打开zabbix截图发邮件。。.日复一日手动处理?如果是这样,这篇干货文章将解放你的双手。文档说明本文档主要介绍使用python脚本指定主机名,自动获取zabbix监控图,下载到本地,形成word文档。大致思路:先通过zabbixAPI获取auth;通过主机名获取主机ID;通过hostID获取g??raphID;然后使用爬虫代码将图片下载到本地;通过python的docx模块插入到word文档中(本文zabbix版本为5.0,python为3.8)。1、自动获取zabbix监控图并保存在本地首先获取zabbix的authID,通过zabbixAPI获取hostid、graphID等信息。打印出authID后保存,然后用它来获取主机ID:#GetauthkeyZABBIX_URL='https://www.zabbix.cn'ZABBIX_USERNAME="user"ZABBIX_PASSWORD="password"url="{}/api_jsonrpc.php".format(ZABBIX_URL)header={"Content-Type":"application/json"}#authuserandpassworddata={"jsonrpc":"2.0","method":"user.login","params":{"user":ZABBIX_USERNAME,"password":ZABBIX_PASSWORD},"id":1,}#因为API接收到的是json字符串,需要转换value=json.dumps(data).encode('utf-8')#打包请求req=request.Request(url,headers=header,data=value)#验证并获取AuthIDtry:#打开打包好的urlresult=request.urlopen(req)exceptExceptionase:print("AuthFailed,PleaseCheckYourNameAndPassword:",e)else:response=result.read()#上面得到的数据是bytes类型的数据,所以需要解码成字符串page=response.decode('utf-8')#将这个json字符串转成python字典page=json.loads(page)result.close()print("AuthSuccessful.TheAuthIDIs:{}".format(page.get('result')))变量主机名即需要查询的主机名。当然也可以通过主机名查询到主机ID。当然也可以通过输入功能进行交互,实现动态查询。#Gethostiddata={"jsonrpc":"2.0","method":"host.get","params":{"output":["hostid","host"],"selectInterfaces":["interfaceid""ip"]},"auth":"XXXXXXXXXXXXXXXXXXXXXXXXXX",#这里auth的值为上面获取的auth"id":2}r=requests.post(url,headers=header,data=json.dumps(data))hostname=abc123withopen(hostname_txt,'r')asf:tmp_list=[x.strip("\n")forxinf.readlines()]forhostnameintmp_list:ifr.json().get('result'):foriinr。json()['result']:ifi['host']==hostname:hostids=i['hostid']使用主机ID查询图ID并保存在本地;通过value传入的value,from和这两个key来确定获取监控图的监控时间段。在这个例子中,设置了一个月;"profileIdx":"web.graphics.filter"中的值是zabbix5.0API的新特性。如果没有传入,get的监控周期为一小时,不可更改。#获取graphid列表和字典classZabbixGraph(object):def__init__(self,url,name,password):self.url=urlself.name=nameself.password=password#Generatecookiecookiejar=http.cookiejar.CookieJar()#初始化cookiejar时=cookielib.CookieJar()urlOpener=urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cookiejar))#urlOpener=urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar))values={"name":self.name,'密码':self.password,'autologin':1,"enter":'Signin'}data=parse.urlencode(values).encode("utf-8")#data=urllib.urlencode(values)request=urllib。request.Request(url,data)try:urlOpener.open(request,timeout=10)self.urlOpener=urlOpenerexceptValueError:print("打开网页失败")defGetGraph(self,url,values,p_w_picpath_dir):key=values.keys()print(values)#在底部显示传入的值if"graphid"notinkey:print("请确认是否输入graphid")sys.exit(1)#下面的if是给定的默认值if"period"notinkey:#默认获取一天的数据,以秒为单位values["period"]=2626560if"stime"notinkey:#默认为当前时间开始值["stime"]=datetime.datetime.now().strftime('%Y%m%d%H%M%S')if"width"notinkey:values["width"]=800if"height"notinkey:values["height"]=200data=parse.urlencode(values).encode("utf-8")#data=urllib.urlencode(values)request=urllib.request。请求(url,数据)url=self.urlOpener.open(请求)p_w_picpath=url.read()p_w_picpathname="%s/%s.png"%(p_w_picpath_dir,values["hostname"]+"_images"+values["name"])f=open(p_w_picpathname,'wb+')f.write(p_w_picpath)f.close()graph_id_data={"jsonrpc":"2.0","method":"graph.get","params":{"output":"extend","hostids":hostids,"sortfield":"name"},"auth":"XXXXXXXXXXXXXXXXXXXXXXXXXXXX","id":1}graph_data=requests.post(url,headers=header,data=json.dumps(graph_id_data))graph_list_x=[]graph_dict_name={}ifgraph_data.json().get('result'):foriingraph_data.json()['result']:graph_id=i['graphid']graph_name_x=i['name']graph_name=graph_name_x.replace("/","_")graph_dict_name[graph_id]=graph_namegraph_list_x.append(graph_id)#================================================================#这个url是用来获取图片的,请注意是饼图与此网址不同,请慎重观看!gr_url="https://www.zabbix.cn/chart2.php"#登录地址indexURL="https://www.zabbix.cn/index.php"username="user"password="password"#为图片存储directoryp_w_picpath_dir="/picture"#图片的参数,字典至少传入graphidforkey,valueingraph_dict_name.items():values={"graphid":key,"name":value,"hostname":hostname,"width":800,"height":200,"from":"now-30d","to":"now","profileIdx":"web.graphics.filter"}b=ZabbixGraph(indexURL,username,password)b.GetGraph(gr_url,values,p_w_picpath_dir)2.将图片编辑成word,然后根据图名写word:fromdocximportDocumentfromdocx.sharedimportInchesimportosfromPILimportImage#要插入的图片所在的文件夹pwd=os.getcwd()fold='picture'fold_DS=fold+'/'+'.DS_Store'word=pwd+"/"+"Word文档"try:os.mkdir(pwd+'/'+fold,755)except:print("目录已经存在!不用再创建")#os.walk(fold)没有返回值,所以这样做所以显然没有结果,是错误的#pics=list(os.walk(fold)[3])##pics.pop()#print(pics)#pics是图片的名字#root是字符串类型,dirs和pics是列表类型try:os.remove(fold_DS)except:print("no.DS_Storefile")forroot,dirs,picsinos.walk(fold):doc=Document()foriinrange(0,len(pics)):文件路径h=root+'/'+str(pics[i])string=str(pics[i].strip(".png"))#print(string)try:doc.add_paragraph(string)doc.add_picture(filepath,width=Inches(6),height=Inches(3))exceptException:pic_tmp=Image.open(filepath)#如果格式有问题,使用save转为默认的jpg格式pic_tmp.save(pic_tmp)#将处理后的图片放入Document变量docdoc.add_picture(filepath,width=Inches(6),height=Inches(3))#将Document变量doc保存到指定路径的docx文件中doc.save(word)#输出保存成功的标志print("pic",string,"successfullyadded.")三、python模块本次使用的模块,运行前检查宿主机是否安装。本次执行所需的模块一般需要单独安装。有四个模块:urllib3、requests、Pillow和python-docx。importjsonimportrequestsfromurllibimportrequest,parsefromurllib.requestimporturlopenimportsysimportdatetimeimporturllib.requestimporthttp.cookiejarimportosimportsslfromdocximportDocumentfromdocx.sharedimportInches四、注意事项如果有同学的zabbix使用https访问方式,需要在proxy中跳过证书验证。ssl._create_default_https_context=ssl._create_unverified_context打开获取的图片提示文件损坏。使用其他代码编辑器打开查看代码,发现是登录失败的问题。您需要检查登录账号和方式是否正确。
