pnp4nagios的模板

安装pnp4nagios后,我写了一个数据转换脚本,把我的数据按「pnp4nagios的数据格式」输出到spool目录,在「pnp4nagios的安装」中我启动了npcd进程,并且配置spool目录为/diska/pnp4nagios/spool,因此流程为:

  1. 启动npcd进程/etc/init.d/npcd start
  2. 我的数据转换脚本以perfdata_开头生成文件,输出到/diska/pnp4nagios/spool
  3. npcd扫描到文件,调用脚本/home/pnp4nagios/libexec/process_perfdata.pl处理数据,写rrd文件
  4. 在日志目录/diska/pnp4nagios/perf_logs查看npcd.logperfdata.log

对于样例数据:

  1. DATATYPE::SERVICEPERFDATA TIMET::1378779841 HOSTNAME::zh_v542 SERVICEDESC::PING SERVICECHECKCOMMAND::check_icmp SERVICEPERFDATA::rta=92.412ms;200.000;500.000;0; pl=0%;40;80;; rtmax=97.281ms;;;; rtmin=86.727ms;;;;

经处理后,在rrd目录/diska/pnp4nagios/perfdata会生成一个zh_v542子目录,目录下有ping.xmlping.rrd两个文件。当我们访问http://localhost/pnp4nagios/index.php/graph?host=zh_v542&srv=check_icmp时,pnp4nagios的处理大概为:

  1. 扫描参数host下的所有xml文件,读取到/diska/pnp4nagios/perfdata/zh_v542/ping.xml,显示目前有一个ping的服务
  2. 扫描参数srv指定的模板,扫描/home/pnp4nagios/share/templates/home/pnp4nagios/share/templates.dist,按文件名匹配一个check_icmp.php的模板文件
  3. 找到/home/pnp4nagios/share/templates.dist/check_icmp.php,模板文件里配置了2个信息:RRD文件的路径、如何画rrd图。
  4. 如果找不到匹配的模板,则使用默认模板default.php
  5. /diska/pnp4nagios/perfdata/zh_v542/ping.rrd中读取数据,根据模板的rrd函数,画出rrd图。这需要对rrd的一些画图方式有一定的了解。

一个check_icmp.php的模板内容大概为:

<?php
#
# Copyright (c) 2006-2010 Joerg Linge (http://www.pnp4nagios.org)
# Plugin: check_icmp [Multigraph]
#
# RTA
#
$ds_name[1] = "Round Trip Times";
$opt[1]  = "--vertical-label \"RTA\"  --title \"Ping times\" ";
$def[1]  =  rrd::def("var1", $RRDFILE[1], $DS[1], "AVERAGE") ;
$def[1] .=  rrd::gradient("var1", "ff5c00", "ffdc00", "Round Trip Times", 20) ;
$def[1] .=  rrd::gprint("var1", array("LAST", "MAX", "AVERAGE"), "%6.2lf $UNIT[1]") ;
$def[1] .=  rrd::line1("var1", "#000000") ;

if($WARN[1] != ""){
        if($UNIT[1] == "%%"){ $UNIT[1] = "%"; };
        $def[1] .= rrd::hrule($WARN[1], "#FFFF00", "Warning  ".$WARN[1].$UNIT[1]."\\n");
}
if($CRIT[1] != ""){
        if($UNIT[1] == "%%"){ $UNIT[1] = "%"; };
        $def[1] .= rrd::hrule($CRIT[1], "#FF0000", "Critical ".$CRIT[1].$UNIT[1]."\\n");
}
#
# Packets Lost
$ds_name[2] = "Packets Lost";
$opt[2] = "--vertical-label \"Packets lost\" -l0 -u105 --title \"Packets lost\" ";

$def[2]  =  rrd::def("var1", $RRDFILE[2], $DS[2], "AVERAGE");
$def[2] .=  rrd::gradient("var1", "ff5c00", "ffdc00", "Packets Lost", 20) ;
$def[2] .=  rrd::gprint("var1", array("LAST", "MAX", "AVERAGE"), "%3.0lf $UNIT[2]") ;
$def[2] .=  rrd::line1("var1", "#000000") ;

$def[2] .= rrd::hrule("100", "#000000") ;

if($WARN[2] != ""){
        if($UNIT[2] == "%%"){ $UNIT[2] = "%"; };
        $def[2] .= rrd::hrule($WARN[2], "#FFFF00", "Warning  ".$WARN[2].$UNIT[2]."\\n");
}
if($CRIT[2] != ""){
        if($UNIT[2] == "%%"){ $UNIT[2] = "%"; };
        $def[2] .= rrd::hrule($CRIT[2], "#FF0000", "Critical ".$CRIT[2].$UNIT[2]."\\n");
}

模板主要是2个数组$opt$def, 可以使用xml文件里的字段,比如DS, NAME, RRDFILE等,具体的见pnp4nagios关于模板的介绍吧。对于字段不确定的模板,可以这样写

<?php

foreach ($this->DS as $KEY=>$VAL) {
    #$DATA[$VAL["NAME"]] = $VAL;
    $DATA[$VAL["LABEL"]] = $VAL;
}

ksort($DATA);

# print $DATA to browser
#throw new Kohana_exception(print_r($DATA,TRUE));

$i = 0;
foreach ($DATA as $key => $val){
    $title = "$key";
    $ds_name[$i] = "$key";
        $opt[$i] = "-b 1000 --vertical-label \"%\" -l0 --title \"$hostname $title\" ";
    $key = $val["NAME"];
    $def[$i] = rrd::def("$key", $val["RRDFILE"], 1, "AVERAGE");
    $def[$i] .= rrd::line1("$key", "#007500", "$title");
    $def[$i] .= rrd::gprint("$key", array("LAST", "AVERAGE", "MAX"), "%10.2lf%s");
    $i ++;
}

#throw new Kohana_exception(print_r($def,TRUE));

?>

对于模板,我想说的一个tip,可以通过throw new Kohana_exception(print_r($def,TRUE));,抛出一个异常信息到浏览器中,查看数据内容,这对于我刚接触模板的人来说,提供了很大的帮助。

到此还以为可以完成工作,没想到npcd调用process_perfdata.pl的单进程处理速度并不理想,3.5w条的数据写入RRD文件,处理了将近30分钟,磁盘IO也很高,而实际上这需要在1分钟内处理完成的。

还要换个方式,后续再记。



– EOF –

Categories: in_lib
Tags: nagios,perl