1

提前感谢您的时间和精力。这是我第一个使用 PHP 和 RRD 的脚本。当我为 SNMP 编写一个简短的程序时,我遇到了 RRD 一个强大的图形输出工具。我试图编写一个简短的操作脚本来模仿图形的输出。我从官方页面尽可能多地阅读了有关 RRD 的文档,并尝试将它们添加到我的 PHP 代码中。我在尝试调试代码时发现了一些函数,这些函数显示我的数据正常输入并按预期进行引用。提供的样本如下:

["last_update"]=>
int(1396917542)
["ds_cnt"]=>
int(3)
["ds_navm"]=>
array(3) {
  [0]=>
  string(10) "ifInOctets"
  [1]=>
  string(11) "ifOutOctets"
  [2]=>
  string(9) "sysUpTime"
}
["data"]=>
array(3) {
  [0]=>
  string(4) "1405"
  [1]=>
  string(4) "1219"
  [2]=>
  string(4) "1893"
 }
}

基于功能:

"$debug = rrd_lastupdate (
                          "".$rrdFile.""
             );"

我很难理解,因为输入正确,并且在编译我的代码时没有显示打印错误,为什么我没有得到任何输出?

我已经将我的工作代码作为示例,以便可能重现和更好地理解我的错误。

<?php

// rrdtool info /var/www/snmp.rrd Debugging command

while (1) {
  sleep (1);
  $file = "snmp";
  $rrdFile = dirname(__FILE__) . "/".$file.".rrd";
  $in = "ifInOctets";
  $out = "ifOutOctets";
  $count = "sysUpTime";

  $options = array(
       "--start","now -10s", // Now -10 seconds (default)
       "--step", "10", // Step size of 300 seconds 5 minutes
       "DS:".$in.":COUNTER:20:U:U",
       "DS:".$out.":COUNTER:20:U:U",
       "DS:".$count.":COUNTER:20:U:U",
       /* DS:ds-name:DST:dst arguments
          (DST: GAUGE, COUNTER, DERIVE, and ABSOLUTE):heartbeat:min:max
          heartbeat: in case that there is not input up to 600 seconds
          then the input will characterised as undefined (blank)
          Based on Nyquist rate (Fs >= 2 * Fmax) 300 (step) 600 (heartbeat)
          32-bit = 2^32-1 = 4294967295 (counter ticks)
          64-bit = 2^64-1 = 18446744073709551615 (counter ticks)
          64-bit counter (caution!!!) different oid's
       */
       "RRA:MIN:0.5:10:300",
       "RRA:MIN:0.5:20:600",
       "RRA:MAX:0.5:10:300",
       "RRA:MAX:0.5:20:600",
       "RRA:AVERAGE:0.5:10:300",
       "RRA:AVERAGE:0.5:20:600",
       /* RRA:AVERAGE | MIN | MAX | LAST:xff:steps:rows
          xff range: 0-1 (exclusive) defines the allowed number of unknown
          *UNKNOWN* PDPs to the number of PDPs in the interval. Step defines
          how many of those data points are used to build consolidated data.
          rows defines how many data values are kept in an RRA.
       */
       );

  //create rrd file
  $create = rrd_create(
           "".$rrdFile."",
           $options
           );

  if ($create === FALSE) {
    echo "Creation error: ".rrd_error()."\n";
  }

  $ifInOctets = rand(0, 1500); // ifInOctets (OID: 1.3.6.1.2.1.2.2.1.10)
  $ifOutOctets = rand(0, 2500); // ifOutOctets (OID: 1.3.6.1.2.1.2.2.1.16)
  $sysUpTime = rand(0, 2000); // sysUpTime (OID: 1.3.6.1.2.1.1.3)

  $t = time();

  //update rrd file
  $update = rrd_update(
           "".$rrdFile."",
           array(
             /* Update database with 3 values 
            based on time now (N:timestamp) */
             "".$t.":".$ifInOctets.":".$ifOutOctets.":".$sysUpTime.""
             )
           );

  if ($update === FALSE) {
    echo "Update error: ".rrd_error()."\n";
  }

  $start = "now";
  $title = "Hourly Server Data";

  $final = array(
     "--start","".$start." -10s",
     "--step","10",
     "--title=".$title."",
     "--vertical-label=Bytes/sec",
     "--lower-limit=0",
     //"--no-gridfit",
     "--slope-mode",
     //"--imgformat","EPS",
     "DEF:".$in."_def=".$file.".rrd:".$in.":AVERAGE",
     "DEF:".$out."_def=".$file.".rrd:".$out.":AVERAGE",
     "DEF:".$count."_def=".$file.".rrd:".$count.":AVERAGE",
     "CDEF:inbits=".$in."_def,8,*",
     "CDEF:outbits=".$out."_def,8,*",
     "CDEF:counter=".$count."_def,8,*",
     /* "VDEF:".$in_min."=inbits,MINIMUM",
        "VDEF:".$out_min."=outbits,MINIMUM",
        "VDEF:".$in_max."=inbits,MAXIMUM",
        "VDEF:".$out_max."=outbits,MAXIMUM",
        "VDEF:".$in_av."=inbits,AVERAGE",
        "VDEF:".$out_av."=outbits,AVERAGE", */
     "COMMENT:\\n",
     "LINE:".$in."_def#FF00FF:".$in."",
     "GPRINT:inbits:LAST:last \: %6.2lf %SBps",
     "COMMENT:\\n",
     "LINE:".$out."_def#0000FF:".$out."",
     "GPRINT:outbits:LAST:last \: %6.2lf %SBps",
     "COMMENT:\\n",
     "LINE:".$count."_def#FFFF00:".$count."",
     "GPRINT:counter:LAST:last\: %6.2lf %SBps",
     "COMMENT:\\n",
     );

  // graph output 
  $outputPngFile = rrd_graph(
             "".$file.".png",
             $final
             );

  if ($outputPngFile === FALSE) {
    echo "<b>Graph error: </b>".rrd_error()."\n";
   }

  /*  Returns the first data sample from the 
      specified RRA of the RRD file. */
   $result = rrd_first (
           $rrdFile,
           $raaindex = 0
           );

   if ($result === FALSE) {
     echo "<b>Graph result error: </b>".rrd_error()."\n";
   }

   /* Returns the UNIX timestamp of the most 
      recent update of the RRD database. */
   $last = rrd_last (
        $rrdFile
        );

   if ($last === FALSE) {
      echo "<b>Graph result error: </b>".rrd_error()."\n";
    }

    $info = rrd_info (
        "".$rrdFile.""
        );

    if ($info === FALSE) {
      echo "<b>Graph result error: </b>".rrd_error()."\n";
    }

    /*  Gets array of the UNIX timestamp and the values stored 
        for each date in the most recent update of the RRD database file. */
    $debug = rrd_lastupdate (
           "".$rrdFile.""
           );

     if ($debug === FALSE) {
       echo "<b>Graph result error: </b>".rrd_error()."\n";
     }

     var_dump ($debug);

     /* $version = rrd_version ( );
        echo "This is the version ".$version."\n"; */

} // End of while condition 
?>
4

1 回答 1

2

你的代码有很多问题。

首先,您的 RRD 文件显然会在您的 While 循环的每次迭代中重新创建!这将覆盖前一个循环的更新。

其次,尽管您创建了步长为 10 的 RRD,但您并没有在每个更新循环结束时执行 sleep(10)。您不能比步长更频繁地更新 RRD。

第三,您为 DS 使用了 COUNTER 类型,它假定计数不断增加。但是,您的测试数据是随机数,因此不会增加。减少可能被视为计数器回绕,因此一个巨大的数字超出了您的 DS 的有效范围 - 因此存储了一个未知数。

第四,您需要连续两次更新计数器才能获得有效汇率;您每次迭代都会覆盖您的 RRD 文件,因此永远无法获得此文件。

第五,定义的最小 RRA 的计数为 10;这意味着您需要 10 个数据点才能在 RRA 中创建一个合并点。步长为 10 秒,这意味着您需要运行 110 秒(11 次更新)才能绘制单个数据点。您可能应该尝试添加 Count 1 RRA。

最后,您的图表被请求一个 10 秒的时间窗口。这少于一个 RRA 样本。请记住,您的 r Step 是 10s,而您的最小 RRA 是 count=10,所以合并的 step 是 100s。

我建议您修复循环,以便创建外部;使睡眠等同于 RRD 步骤;添加 Count 1 AVG RRA;并使您的图表请求更长的时间窗口。

于 2014-04-08T04:46:39.760 回答