Как распечатать данные RRD Graph с помощью PHP

Заранее спасибо за ваше время и усилия. Это мой первый скрипт с 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 
?>

person thanos    schedule 08.04.2014    source источник


Ответы (1)


В вашем коде много проблем.

Во-первых, ваш RRD-файл, по-видимому, создается заново при каждой итерации цикла While! Это перезапишет обновление предыдущего цикла.

Во-вторых, хотя вы создаете RRD с размером шага 10, вы не выполняете sleep(10) в конце каждого цикла обновления. Вы не можете обновлять RRD чаще, чем размер шага.

В-третьих, вы использовали тип COUNTER для DS, который предполагает постоянно увеличивающийся счет. Однако ваши тестовые данные представляют собой случайные числа и поэтому не увеличиваются. Уменьшение может быть воспринято как обход счетчика, поэтому огромное число, которое находится за пределами допустимого диапазона для вашего DS, и, следовательно, сохраняется неизвестное.

В-четвертых, вам нужно иметь два последовательных обновления, чтобы счетчик имел действительную скорость; вы перезаписываете свой RRD-файл каждую итерацию, и вам никогда не удается получить это.

В-пятых, ваш наименьший определяемый RRA имеет значение COUNT, равное 10; это означает, что вам нужно 10 точек данных, чтобы сделать одну консолидированную точку в RRA. С шагом 10 секунд это означает, что вам нужно работать в течение 110 секунд (11 обновлений), прежде чем у вас появится хотя бы одна точка данных для построения графика. Вероятно, вам следует попробовать добавить RRA Count 1.

И, наконец, ваш график запрашивается для 10-секундного временного окна. Это меньше, чем один образец RRA. Помните, что ваш r Step равен 10 с, а наименьший RRA равен count=10, поэтому объединенный шаг равен 100 с.

Я предлагаю вам исправить петлю, чтобы создание выходило наружу; сделать сон эквивалентным шагу RRD; добавить Count 1 AVG RRA; и сделайте запрос графика на более длительное временное окно.

person Steve Shipway    schedule 08.04.2014
comment
Спасибо за предоставленную информацию и анализ моей системы. Я пробовал некоторые модификации, но все равно получаю один и тот же пустой график. Модификации, которые я применил: sleep (10),"DS:".$in.":GAUGE:2:U:U","--step", "1","RRA:MIN:0.5:2:1" и шаг графика: "--step","15". Я снова не в том направлении? Я ценю ваше время и усилия. - person thanos; 08.04.2014
comment
Я заметил, что я неправильно указал время сна, а время графика должно быть наоборот: sleep (15) и "--step","15", но все же эта доза не решает мою проблему. Я снова что-то упускаю, что я еще не могу понять. - person thanos; 08.04.2014
comment
У вас должен быть вызов slepp() того же размера, что и определение --step. Кроме того, если вы не переместите свой вызов rrd_create за пределы цикла while() и не сделаете, вы никогда ничего не получите! Наконец, если вы хотите использовать эти случайные значения обновления, вы должны использовать DS типа GAUGE, а не COUNTER. Разберитесь со всеми 6 проблемами, которые я упомянул в своем исходном посте, если хотите, чтобы это сработало. - person Steve Shipway; 09.04.2014
comment
Спасибо за ваше время и усилия. Я буду работать со значениями, чтобы попытаться понять, как работает база данных rrd и как она обновляет данные. - person thanos; 10.04.2014