vlambda博客
学习文章列表

修改Zabbix制图源码方便制作ZABBIX报表

      使用Zabbix常需要根据需求进行二次开发,通常使用zabbix-api来进行相关开发,但使用相关API进行数据图表制作时会有许多因素要考虑,因为ZABBIX有History与Trend数据,制作线性趋势图时需要考虑时间范围,使用这些数据制图比较麻烦,个人为了避免重复造轮子就直接使用ZABBIX自身WEB出图功能,使用类爬虫技术来抓取图片。在抓取图片时我们还需要输出相关数据作图成EXCEL表格,输出如CPU的最大使用率,平均使用率等数据,这些开始我们使用API来获取相关数据,经过一段时间使用发现经常这些数据与使用爬虫抓取的图片上的数据不相等,从原理上来讲这种差别可能是时间精度等方面的差别导致的,两种计算方法很难修改一致,所以考虑是否可以在获取图片时直接获取这些呢?

       经研究ZABBIX的web源码,同时考虑在获取图片的同时获取这些数据,发现在绘图时相关源码已获取了相关数据,在绘图的同时添加这些数据到reponse的headers中,这样客户端在获取图片数据的同时通过headers也可以获取这些数据。

       1.修改CLineGraphDraw.php(注:这里修改的ZABBIX源码版本是5.4.6),在下面的代码

} // draw legend of an item without data

前添加以下代码:

//将item的最新值,最大值,最小值与平均值添加到headersheader('last-'.$this->items[$i]['itemid'].':'.$this->getLastValue($i));header('max-'.$this->items[$i]['itemid'].':'.max($data['max']));header('min-'.$this->items[$i]['itemid'].':'.min($data['min']));header('avg-'.$this->items[$i]['itemid'].':'.$data['avg_orig']);

2.客户端获取图片的同时输出最大值,平均值等。

def pic_save(ip,name,itemids,stime,period,curtime,pic_dir,opener,vals=dict()): graph_url = '%s/chart.php' % (zbxserver) graph_args=urllib.urlencode({ #"itemids[]":itemids, "width":'600', #定义图片宽度 "height":'156'}) #定义时长,取1天的数据  graph_args = graph_args+"&"+urllib.urlencode({ "from":datetime.datetime.fromtimestamp(stime), #图形开始时间 "to":datetime.datetime.fromtimestamp(curtime), "type":0, "profileIdx":'web.item.graph.filter'}) #定义时长,取1天的数据 for itemid in itemids: graph_args=graph_args+"&"+urllib.urlencode({"itemids[]":itemid})
print('%s?%s' % (graph_url,graph_args)) response=opener.open(graph_url,graph_args)    #获取最大、最小与平均值到vals for itemid in itemids: vals['max-%s'%(itemid)]=response.info().getheader('max-%s'%(itemid)) vals['min-%s'%(itemid)]=response.info().getheader('min-%s'%(itemid))        vals['avg-%s'%(itemid)]=response.info().getheader('avg-%s'%(itemid))    #读取图片数r居并保存成本地文件并将图片文件路径作为函数返回值    data = response.read() #response.info().getheader('Set cookie') picname = ip + '-' + name +'.png' pic_save_path = os.path.join(pic_dir,picname) file=open(pic_save_path,'wb') file.write(data) file.flush() file.close() return pic_save_path

通过这个函数在获取输出图片的同时可以从vals中获取监控项的最大,最小与平值,从而直接输出到EXCEL报表,而不需要另外计算,大大方便了有关报表制作。