当前位置: 首页 > 后端技术 > PHP

Grafana+prometheus+php自动创建监控图

时间:2023-03-29 14:16:03 PHP

背景在grafana+prometheus+php监控系统实践篇中,我们实现了自己的第一个监控图。现在我们有一个新的需求,需要对不同的节点进行监控,并进行汇总监控;按照我们之前手动创建dashboard的方法,每个新节点都需要手动修改prometheus配置,需要在grafana系统中创建dashboard。当节点比较少的时候,这个方法也可以满足,但是当节点数量增加的时候,会增加很大一部分的工作量,并且有每次创建的图表规则不一致的风险,所以我们的需求是让grafana在添加仪表板后自动创建一个新节点。实现流程操作步骤Prometheus调用中间件中间件收集各节点数据校验中间件数据有效性DebugdashboardAPI接口编写节点变更事件处理1.Prometheus调用中间件1.修改prometheus配置文件修改配置文件的目的是改变之前直接连接单个节点的地址改为中间件地址。之前单节点的uri是'==/api/v1/rrd/metrics==',现在需要改成中间件地址'==/api/v1/rrd/toolSpool==',所以新配置文件内容如下:---global:scrape_interval:5sscrape_timeout:3sscrape_configs:-job_name:'mysql'scrape_interval:5sstatic_configs:-targets:['192.168.43.34:9104']labels:instance:192.168.43.34-job_name:'media'scrape_interval:3smetrics_path:"/api/v1/rrd/toolSpool"static_configs:-targets:['gslb.offcncloud.com:8080']1.2重启prometheus修改配置文件后,你需要让配置文件生效,所以需要重启prometheus。dockerrestartdocker本身提供了重启命令,所以只需要输入下面的命令,注意后面是容器的名字。dockerrestartprometheusmacrestartmacrestart比较简单,先终止之前的任务,然后使用启动命令prometheus--config.file=/tmp/prometheus.yml二、中间件收集各个节点的数据2.1用途作用中间件的功能是将各个节点的数据进行汇总,然后一次性返回给prometheus。有很多方法可以实现这个中间件。在实施之前,我们也搜索了一些资料。关联;但是我觉得这个配置并不简单,这个中间件的功能也比较简单,所以还是用PHP写了一个中间件。参考资料:http://blog.51cto.com/xujpxm/...2.2中间件需要的效果:拉取所有节点数据,这是标记每个节点的核心功能,用于区分哪个节点以后是汇总和输出,需要一个汇总仪表盘2.3获取节点数据,并添加标记获取每个节点的数据,先获取所有节点列表的名称,然后用节点的IP地址拼接URL,最后通过curl请求这个地址来获取节点数据;拿到数据后,我们还需要对每个节点返回的数据进行标记,用{}包含,因为prometheus支持这种格式,伪代码如下:ip}/api/v1/rrd/metrics";//3。获取数据$tmp=file_get_contents($url);//4。在每个节点中插入主机属性,当过滤单个节点时$tmp=str_replace('',"{host=\"{$name->ip}\"}",$tmp);$str.=$tmp;}2.4汇总输出我们的核心需求是看到所有节点的汇总状态,所以在获取到每个节点的数据后,需要进行累加。prometheus好像没有直接支持,只好在中间件主线积累总结了。//限制需要汇总统计,先把字符串分成一个数组$arr=explode(PHP_EOL,$str);$tmpArr=[];//遍历数组foreach($arras$val){//将每一行再次拆分$valArr=explode("",$val);//5。汇总统计信息if(!empty($valArr[0])&&is_string($valArr[0])&&is_numeric($valArr[2])){$tmpArr[$valArr[0]]=isset($tmpArr[$valArr[0]])?($tmpArr[$valArr[0]]+$valArr[2]):$valArr[2];}}//6。摘要输出foreach($tmpArras$key=>$num){echo"{$key}_total$num".PHP_EOL;}echo$str;}2.5输出最终结果当中间件处理完成后,我们需要每个节点的数据,需要在数据中标记节点,还需要一个汇总数据,所以中间件返回数据如下:media_connectNum_total0media_network_total0media_on_push_total2media_connectNum{host="192.168.43.46:8080"}0media_network{host="192.168.43.46:8080"}0media_on_push{host="192.168.43.46:80_12Num."}1.0.1:8080"}0media_network{host="127.0.0.1:8080"}0media_on_push{host="127.0.0.1:8080"}13.验证中间件数据的合法性现在我们的prometheus已经启动了,中间件也运行正常,那么此时prometheus和Grafana应该有相应的变化,我们可以根据变化来判断我们之前的处理是否成功3.1prometheus数据校验当我们的配置文件和中间件发生变化时,对应的变化应该是数据仓库,所以我们可以打开prometheus的web界面,url地址(http://192.168.43.34:9090/graph),在filter中输入media_network,然后filter,如果能看到多条返回记录,说明验证成功,如下图所示。3.2Grafana数据校验当prometheus数据仓库中的数据发生变化时,grafanadashboard也应该发生变化。最明显的变化如下图所示,标签变成了双重。quantity”变成了double。原因是多个节点返回了多份数据,而我们在使用Grafana绘制的时候,过滤项只进入了其中的key部分,并没有过滤里面的属性,所以会有一样多items因为有节点,如果数字对上就说明Grafana也验证成功了。3.3设置汇总图现在我们编辑之前的dashboard,将之前的filteringkey改为filterkey+upperattribute。设置方法如下图所示。设置完成后,我们看到的就是摘要仪表盘。第一个核心需求已经实现。3.4设置节点模板设置完汇总图后,我们还要实现第二个核心需求,即自动创建单节点dashboard。我们首先需要手动创建一个单节点的图,和第一篇文章的创建方法是一样的。在设置过滤项的时候,我们填写的内容应该包括属性。属性的作用可以过滤节点,如下图所示:4.调试dashboardAPI接口API官方文档网址:http://docs.grafana.org/http_...4.1创建API接口我们的目标是grafana可以在添加新节点的时候自动创建对应的dashboard,所以我们需要使用到grafana的API接口,使用前需要创建key进行授权,创建过程如下:添加一个api,填写keyname中任意名字,然后角色选择admin权限,点击添加按钮创建函数在grafana页面看到弹出提示,我们需要先复制放到一个位置,因为key后面看不到,运行如下命令:使用终端进行访问测试,如果返回结果如下,则说明密钥可以使用4.2使用postman调试现在先别急着用PHP调试,可以先用Postman调试,我们要调试的不是url地址on刚才的弹框,是创建dashboard的地址。官方文档中的请求信息如下:POST/api/dashboards/dbHTTP/1.1Accept:application/jsonContent-Type:application/jsonAuthorization:BearereyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk{"dashboard":{"id":null,"uid":null,"title":"ProductionOverview","tags":[",templatedone"]":"browser","schemaVersion":16,"version":0},"folderId":0,"overwrite":false}使用postman请求截图{"id":23,"slug":"production-overview","status":"success","uid":"ID2FFcciz","url":"/d/ID2FFcciz/production-overview","version":1}当返回以上结果时,表示创建成功。4.3导出模板现在我们需要导出一个之前创建的节点dashboard,作为template,以及导出dashboard的配置方法比较简单,将上面的json数据保存到grafana.json文件中,保存json文件的时候需要注意,导出的json配置不能直接使用,因为jsonprometheus创建的dashboard的格式不是这样的,我们需要对json内容做一点处理,前后加一些字符,效果如下{"dashboard":------Exportthecontentofjsoninthemiddle--------,"overwrite":false}注意:既然是模板文件,里面肯定有一些变化,比如title和hostattribute,所以我们要在模板中做一个标记,比如标题部分###可以使用###title,方便后面的文字替换,具体可以参考我的配置文件。保存之后,还可以使用postman验证这个json的内容。使用postman正常添加后,我们将使用PHP的curl来实现4.4编写PHP请求代码,现在已经保证我们的json数据没有问题了,那么现在使用PHP的curl创建一个dashboard,伪代码如下:/***通过curl获取数据*@param$url*@parambool$isHearder*@parambool$post*@returnmixed*/functionhttp_request($url,$isHearder=null,$post='GET',$data=null,$timeout=1){//初始化curl$ch=curl_init($url);//设置URL地址curl_setopt($ch,CURLOPT_URL,$uRL);//设置头信息if(!empty($isHearder)){curl_setopt($ch,CURLOPT_HEADER,0);curl_setopt($ch,CURLOPT_HTTPHEADER,$isHearder);}//如果是post,把数据传过去if(($post=='POST')&&$data){#如果data是数组,转成json格式if(is_array($data)){$data=json_encode($data);}curl_setopt($ch,CURLOPT_POST,1);curl_setopt($ch,CURLOPT_POSTFIELDS,$data);}//如果是删除方法,就是删除请求if($post=='DELETE'){curl_setopt($ch,CURLOPT_CUSTOMREQUEST,'DELETE');}//以毫秒为单位设置超时时间curl_setopt($ch,CURLOPT_CONNECTTIMEOUT_MS,$timeout*1000);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//执行CURL时间$result=curl_exec($ch);//如果有异常,记录在日志中$curl_errno=curl_errno($ch);如果($curl_errno>0){LogModel::addlog('timeout');}//关闭URL并返回数据curl_close($ch);return$result;}5.编写节点变更事件处理以上操作完成后,我们前期的基础工作就已经完成了,接下来要做的就是在创建节点时调用PHP发起请求5.1新添加的节点通过api触发部分伪代码创建dashboard。普罗米修斯仪表板中有一个uid键。这个key可以自己控制,必须保证它的唯一性(如果json模板中的uid项设置为null,prometheus会自动帮你生成一个);我们可以使用节点IP地址的hash值作为它的uid,这样以后换dashboard的时候只要有ip就可以得到uid,而不用再存一份,比如下面的伪代码:/***创建图表*@param$str*@paramarray$params*@return\Illuminate\Http\JsonResponse*/publicfunctionreplaceNodeInfo($ip){//接收节点触发事件$uid=md5($知识产权);//设置header,认证信息$header=array("Content-Type:application/json",'Authorization:BearereyJrIjoicnhTMklodFMzaDRsUXFoUFFiZ2tSRnQ3TnI4WEVqQlEiLCJuIjoidGFuZ3Fpbmdzb25nIiwiaWQi$Ojthistemplate);//读取$json模板)->readJsonData();//替换模板中需要替换的位置$jsonstr=str_replace('###node###',$ip,$jsonstr);$jsonstr=str_replace('###uid###',$uid,$jsonstr);//发起curl请求http_request('http://192.168.43.34:3000/api/dashboards/db',$header,'POST',$jsonstr);}5.2检查效果时使用PHP的curl请求后,我们在grafanadashboard管理界面可以看到PHP创建的图表。当出现下图的效果时,就代表成功了:使用了,所以我们还要删除相应的仪表板。我们前面产生的uid是ip地址的hash值,所以我们删除的时候也可以取ip对应的hash值,通过这个uid删除dashboard。以下伪代码:/***删除节点节点视图信息*@paramRequest$req*/publicfunctiondelNodeViewInfo(Request$req){//接收参数$params=$req->all();$ip=$params['ip'];$uid=md5($ip);//设置认证信息$header=array("Content-Type:application/json",'Authorization:BearereyJrIjoicnhTMklodFMzaDRsUXFoUFFiZ2tSRnQ3TnI4WEVqQlEiLCJuIjoidGFuZ3Fpbmdzb25nIiwiaWQiOjF9');//执行删除事件http_request("http://192.168.43.34:3000/api/dashboards/uid/{$uid}",$header,'DELETE');}作者:唐庆松微信:songboy8888