jablonka.czprosek.czf

weathermap

Subversion Repositories:
[/] [lib/] [datasources/] [WeatherMapDataSource_rrd.php] - Blame information for rev 95

 

Line No. Rev Author Line
11simandl<?php
2// RRDtool datasource plugin.
3// gauge:filename.rrd:ds_in:ds_out
4// filename.rrd:ds_in:ds_out
5// filename.rrd:ds_in:ds_out
6//
785simandl 
8include_once(dirname(__FILE__)."/../ds-common.php");
9 
101simandlclass WeatherMapDataSource_rrd extends WeatherMapDataSource {
11 
12 function Init(&$map)
13 {
1485simandl global $config;
15 #if (extension_loaded('RRDTool')) // fetch the values via the RRDtool Extension
16 #{
17 # debug("RRD DS: Using RRDTool php extension.\n");
18# return(TRUE);
19# }
20# else
21# {
22 if($map->context=='cacti')
23 {
24 debug("RRD DS: path_rra is ".$config["rra_path"]." - your rrd pathname must be exactly this to use poller_output\n");
25 // save away a couple of useful global SET variables
26 $map->add_hint("cacti_path_rra",$config["rra_path"]);
27 $map->add_hint("cacti_url",$config['url_path']);
28 }
29 if (file_exists($map->rrdtool)) {
30 if((function_exists('is_executable')) && (!is_executable($map->rrdtool)))
31 {
32 warn("RRD DS: RRDTool exists but is not executable? [WMRRD01]\n");
33 return(FALSE);
34 }
35 $map->rrdtool_check="FOUND";
36 return(TRUE);
37 }
38 // normally, DS plugins shouldn't really pollute the logs
39 // this particular one is important to most users though...
40 if($map->context=='cli')
411simandl {
4285simandl warn("RRD DS: Can't find RRDTOOL. Check line 29 of the 'weathermap' script.\nRRD-based TARGETs will fail. [WMRRD02]\n");
431simandl }
4485simandl if($map->context=='cacti')
45 { // unlikely to ever occur
46 warn("RRD DS: Can't find RRDTOOL. Check your Cacti config. [WMRRD03]\n");
47 }
48# }
491simandl 
50 return(FALSE);
51 }
52 
53 function Recognise($targetstring)
54 {
55 if(preg_match("/^(.*\.rrd):([\-a-zA-Z0-9_]+):([\-a-zA-Z0-9_]+)$/",$targetstring,$matches))
56 {
57 return TRUE;
58 }
59 elseif(preg_match("/^(.*\.rrd)$/",$targetstring,$matches))
60 {
61 return TRUE;
62 }
63 else
64 {
65 return FALSE;
66 }
67 }
68 
6985simandl function wmrrd_read_from_poller_output($rrdfile,$cf,$start,$end,$dsnames, &$data, &$map, &$data_time, &$item)
70 {
71 global $config;
72 
73 debug("RRD ReadData: poller_output style\n");
74 
75 if(isset($config))
76 {
77 // take away the cacti bit, to get the appropriate path for the table
78 // $db_rrdname = realpath($rrdfile);
79 $path_rra = $config["rra_path"];
80 $db_rrdname = $rrdfile;
81 $db_rrdname = str_replace($path_rra,"<path_rra>",$db_rrdname);
82 debug("******************************************************************\nChecking weathermap_data\n");
83 foreach (array(IN,OUT) as $dir)
84 {
85 debug("RRD ReadData: poller_output - looking for $dir value\n");
86 if($dsnames[$dir] != '-')
87 {
88 debug("RRD ReadData: poller_output - DS name is ".$dsnames[$dir]."\n");
89 
90 $SQL = "select * from weathermap_data where rrdfile='".mysql_real_escape_string($db_rrdname)."' and data_source_name='".mysql_real_escape_string($dsnames[$dir])."'";
91 
92 $SQLcheck = "select data_template_data.local_data_id from data_template_data,data_template_rrd where data_template_data.local_data_id=data_template_rrd.local_data_id and data_template_data.data_source_path='".mysql_real_escape_string($db_rrdname)."' and data_template_rrd.data_source_name='".mysql_real_escape_string($dsnames[$dir])."'";
93 $SQLvalid = "select data_template_rrd.data_source_name from data_template_data,data_template_rrd where data_template_data.local_data_id=data_template_rrd.local_data_id and data_template_data.data_source_path='".mysql_real_escape_string($db_rrdname)."'";
94 
95 $worst_time = time() - 8*60;
96 $result = db_fetch_row($SQL);
97 // OK, the straightforward query for data failed, let's work out why, and add the new data source if necessary
98 if(!isset($result['id']))
99 {
100 debug("RRD ReadData: poller_output - Adding new weathermap_data row for $db_rrdname:".$dsnames[$dir]."\n");
101 $result = db_fetch_row($SQLcheck);
102 if(!isset($result['local_data_id']))
103 {
104 $fields = array();
105 $results = db_fetch_assoc($SQLvalid);
106 foreach ($results as $result)
107 {
108 $fields[] = $result['data_source_name'];
109 }
110 if(count($fields) > 0)
111 {
112 warn("RRD ReadData: poller_output: ".$dsnames[$dir]." is not a valid DS name for $db_rrdname - valid names are: ".join(", ",$fields)." [WMRRD07]\n");
113 }
114 else
115 {
116 warn("RRD ReadData: poller_output: $db_rrdname is not a valid RRD filename within this Cacti install. <path_rra> is $path_rra [WMRRD08]\n");
117 }
118 }
119 else
120 {
121 // add the new data source (which we just checked exists) to the table.
122 // Include the local_data_id as well, to make life easier in poller_output
123 // (and to allow the cacti: DS plugin to use the same table, too)
124 $SQLins = "insert into weathermap_data (rrdfile, data_source_name, sequence, local_data_id) values ('".mysql_real_escape_string($db_rrdname)."','".mysql_real_escape_string($dsnames[$dir])."', 0,".$result['local_data_id'].")";
125 debug("RRD ReadData: poller_output - Adding new weathermap_data row for data source ID ".$result['local_data_id']."\n");
126 db_execute($SQLins);
127 }
128 }
129 else
130 { // the data table line already exists
131 debug("RRD ReadData: poller_output - found weathermap_data row\n");
132 // if the result is valid, then use it
133 if( ($result['sequence'] > 2) && ( $result['last_time'] > $worst_time) )
134 {
135 $data[$dir] = $result['last_calc'];
136 $data_time = $result['last_time'];
137 debug("RRD ReadData: poller_output - data looks valid\n");
138 }
139 else
140 {
141 $data[$dir] = 0;
142 debug("RRD ReadData: poller_output - data is either too old, or too new\n");
143 }
144 // now, we can use the local_data_id to get some other useful info
145 // first, see if the weathermap_data entry *has* a local_data_id. If not, we need to update this entry.
146 $ldi = 0;
147 if(!isset($result['local_data_id']) || $result['local_data_id']==0)
148 {
149 $r2 = db_fetch_row($SQLcheck);
150 if(isset($r2['local_data_id']))
151 {
152 $ldi = $r2['local_data_id'];
153 debug("RRD ReadData: updated local_data_id for wmdata.id=" . $result['id'] . "to $ldi\n");
154 // put that in now, so that we can skip this step next time
155 db_execute("update weathermap_data set local_data_id=".$r2['local_data_id']." where id=".$result['id']);
156 
157 }
158 }
159 else
160 {
161 $ldi = $result['local_data_id'];
162 }
163 
164 if($ldi>0) UpdateCactiData($item, $ldi);
165 }
166 }
167 else
168 {
169 debug("RRD ReadData: poller_output - DS name is '-'\n");
170 }
171 }
172 }
173 else
174 {
175 warn("RRD ReadData: poller_output - Cacti environment is not right [WMRRD12]\n");
176 }
177 
178 debug("RRD ReadData: poller_output - result is ".($data[IN]===NULL?'NULL':$data[IN]).",".($data[OUT]===NULL?'NULL':$data[OUT])."\n");
179 debug("RRD ReadData: poller_output - ended\n");
180 }
181 
182 function wmrrd_read_from_php_rrd($rrdfile,$cf,$start,$end,$dsnames, &$data ,&$map, &$data_time,&$item)
183 {
184 // not yet implemented - use php-rrdtool to read rrd data. Should be quicker
185 if ((1==0) && extension_loaded('RRDTool')) // fetch the values via the RRDtool Extension
186 {
187 // for the php-rrdtool module, we use an array instead...
188 $rrdparams = array("AVERAGE","--start",$start,"--end",$end);
189 $rrdreturn = rrd_fetch ($rrdfile,$rrdparams,count($rrdparams));
190 print_r($rrdreturn);
191 // XXX - figure out what to do with the results here
192 $now = $rrdreturn['start'];
193 $n=0;
194 do {
195 $now += $rrdreturn['step'];
196 print "$now - ";
197 for($i=0;$i<$rrdreturn['ds_cnt'];$i++)
198 {
199 print $rrdreturn['ds_namv'][$i] . ' = '.$rrdreturn['data'][$n++]." ";
200 }
201 print "\n";
202 } while($now <= $rrdreturn['end']);
203 }
204 }
205 
206 # rrdtool graph /dev/null -f "" -s now-30d -e now DEF:in=../rra/atm-sl_traffic_in_5498.rrd:traffic_in:AVERAGE DEF:out=../rra/atm-sl_traffic_in_5498.rrd:traffic_out:AVERAGE VDEF:avg_in=in,AVERAGE VDEF:avg_out=out,AVERAGE PRINT:avg_in:%lf PRINT:avg_out:%lf
207 
208 function wmrrd_read_from_real_rrdtool_aggregate($rrdfile,$cf,$aggregatefn,$start,$end,$dsnames, &$data, &$map, &$data_time,&$item)
209 {
210 
211 debug("RRD ReadData: VDEF style, for ".$item->my_type()." ".$item->name."\n");
212 
213 $extra_options = $map->get_hint("rrd_options");
214 
215 // Assemble an array of command args.
216 // In a real programming language, we'd be able to pass this directly to exec()
217 // However, this will at least allow us to put quotes around args that need them
218 $args = array();
219 $args[] = "graph";
220 $args[] = "/dev/null";
221 $args[] = "-f";
222 $args[] = "''";
223 $args[] = "--start";
224 $args[] = $start;
225 $args[] = "--end";
226 $args[] = $end;
227 
228 # assemble an appropriate RRDtool command line, skipping any '-' DS names.
229 # $command = $map->rrdtool . " graph /dev/null -f '' --start $start --end $end ";
230 
231 if($dsnames[IN] != '-')
232 {
233 # $command .= "DEF:in=$rrdfile:".$dsnames[IN].":$cf ";
234 # $command .= "VDEF:agg_in=in,$aggregatefn ";
235 # $command .= "PRINT:agg_in:'IN %lf' ";
236 
237 $args[] = "DEF:in=$rrdfile:".$dsnames[IN].":$cf";
238 $args[] = "VDEF:agg_in=in,$aggregatefn";
239 $args[] = "PRINT:agg_in:'IN %lf'";
240 }
241 
242 if($dsnames[OUT] != '-')
243 {
244 # $command .= "DEF:out=$rrdfile:".$dsnames[OUT].":$cf ";
245 # $command .= "VDEF:agg_out=out,$aggregatefn ";
246 # $command .= "PRINT:agg_out:'OUT %lf' ";
247 
248 $args[] = "DEF:out=$rrdfile:".$dsnames[OUT].":$cf";
249 $args[] = "VDEF:agg_out=out,$aggregatefn";
250 $args[] = "PRINT:agg_out:'OUT %lf'";
251 }
252 
253 $command = $map->rrdtool;
254 foreach ($args as $arg)
255 {
256 if(strchr($arg," ") != FALSE)
257 {
258 $command .= ' "' . $arg . '"';
259 }
260 else
261 {
262 $command .= ' ' . $arg;
263 }
264 }
265 $command .= " " . $extra_options;
266 
267 debug("RRD ReadData: Running: $command\n");
268 $pipe=popen($command, "r");
269 
270 $lines=array ();
271 $count = 0;
272 $linecount = 0;
273 
274 if (isset($pipe))
275 {
276 fgets($pipe, 4096); // skip the blank line
277 $buffer='';
278 $data_ok = FALSE;
279 
280 while (!feof($pipe))
281 {
282 $line=fgets($pipe, 4096);
283 debug ("> " . $line);
284 $buffer.=$line;
285 $lines[]=$line;
286 $linecount++;
287 }
288 pclose ($pipe);
289 if($linecount>1)
290 {
291 foreach ($lines as $line)
292 {
293 if(preg_match('/^\'(IN|OUT)\s(\-?\d+[\.,]?\d*e?[+-]?\d*:?)\'$/i', $line, $matches))
294 {
295 debug("MATCHED: ".$matches[1]." ".$matches[2]."\n");
296 if($matches[1]=='IN') $data[IN] = floatval($matches[2]);
297 if($matches[1]=='OUT') $data[OUT] = floatval($matches[2]);
298 $data_ok = TRUE;
299 }
300 }
301 if($data_ok)
302 {
303 if($data[IN] === NULL) $data[IN] = 0;
304 if($data[OUT] === NULL) $data[OUT] = 0;
305 }
306 }
307 else
308 {
309 warn("Not enough output from RRDTool. [WMRRD09]\n");
310 }
311 }
312 else
313 {
314 warn("RRD ReadData: failed to open pipe to RRDTool: ".$php_errormsg." [WMRRD04]\n");
315 }
316 debug ("RRD ReadDataFromRealRRDAggregate: Returning (".($data[IN]===NULL?'NULL':$data[IN]).",".($data[OUT]===NULL?'NULL':$data[OUT]).",$data_time)\n");
317 
318 }
319 
320 function wmrrd_read_from_real_rrdtool($rrdfile,$cf,$start,$end,$dsnames, &$data, &$map, &$data_time,&$item)
321 {
322 debug("RRD ReadData: traditional style\n");
323 
324 // we get the last 800 seconds of data - this might be 1 or 2 lines, depending on when in the
325 // cacti polling cycle we get run. This ought to stop the 'some lines are grey' problem that some
326 // people were seeing
327 
328 // NEW PLAN - READ LINES (LIKE NOW), *THEN* CHECK IF REQUIRED DS NAMES EXIST (AND FAIL IF NOT),
329 // *THEN* GET THE LAST LINE WHERE THOSE TWO DS ARE VALID, *THEN* DO ANY PROCESSING.
330 // - this allows for early failure, and also tolerance of empty data in other parts of an rrd (like smokeping uptime)
331 
332 $extra_options = $map->get_hint("rrd_options");
333 
334 $values = array();
335 $args = array();
336 
337 #### $command = '"'.$map->rrdtool . '" fetch "'.$rrdfile.'" AVERAGE --start '.$start.' --end '.$end;
338 #$command=$map->rrdtool . " fetch $rrdfile $cf --start $start --end $end $extra_options";
339 $args[] = "fetch";
340 $args[] = $rrdfile;
341 $args[] = $cf;
342 $args[] = "--start";
343 $args[] = $start;
344 $args[] = "--end";
345 $args[] = $end;
346 
347 $command = $map->rrdtool;
348 foreach ($args as $arg)
349 {
350 if(strchr($arg," ") != FALSE)
351 {
352 $command .= ' "' . $arg . '"';
353 }
354 else
355 {
356 $command .= ' ' . $arg;
357 }
358 }
359 $command .= " " . $extra_options;
360 
361 
362 debug ("RRD ReadData: Running: $command\n");
363 $pipe=popen($command, "r");
364 
365 $lines=array ();
366 $count = 0;
367 $linecount = 0;
368 
369 if (isset($pipe))
370 {
371 $headings=fgets($pipe, 4096);
372 // this replace fudges 1.2.x output to look like 1.0.x
373 // then we can treat them both the same.
374 $heads=preg_split("/\s+/", preg_replace("/^\s+/","timestamp ",$headings) );
375 
376 fgets($pipe, 4096); // skip the blank line
377 $buffer='';
378 
379 while (!feof($pipe))
380 {
381 $line=fgets($pipe, 4096);
382 debug ("> " . $line);
383 $buffer.=$line;
384 $lines[]=$line;
385 $linecount++;
386 
387 }
388 pclose ($pipe);
389 
390 debug("RRD ReadData: Read $linecount lines from rrdtool\n");
391 debug("RRD ReadData: Headings are: $headings\n");
392 
393 if( (in_array($dsnames[IN],$heads) || $dsnames[IN] == '-') && (in_array($dsnames[OUT],$heads) || $dsnames[OUT] == '-') )
394 {
395 // deal with the data, starting with the last line of output
396 $rlines=array_reverse($lines);
397 
398 foreach ($rlines as $line)
399 {
400 debug ("--" . $line . "\n");
401 $cols=preg_split("/\s+/", $line);
402 for ($i=0, $cnt=count($cols)-1; $i < $cnt; $i++) {
403 $h = $heads[$i];
404 $v = $cols[$i];
405 # print "|$h|,|$v|\n";
406 $values[$h] = trim($v);
407 }
408 
409 $data_ok=FALSE;
410 
411 foreach (array(IN,OUT) as $dir)
412 {
413 $n = $dsnames[$dir];
414 # print "|$n|\n";
415 if(array_key_exists($n,$values))
416 {
417 $candidate = $values[$n];
418 if(preg_match('/^\-?\d+[\.,]?\d*e?[+-]?\d*:?$/i', $candidate))
419 {
420 $data[$dir] = $candidate;
421 debug("$candidate is OK value for $n\n");
422 $data_ok = TRUE;
423 }
424 }
425 }
426 
427 if($data_ok)
428 {
429 // at least one of the named DS had good data
430 $data_time = intval($values['timestamp']);
431 
432 // 'fix' a -1 value to 0, so the whole thing is valid
433 // (this needs a proper fix!)
434 if($data[IN] === NULL) $data[IN] = 0;
435 if($data[OUT] === NULL) $data[OUT] = 0;
436 
437 // break out of the loop here
438 break;
439 }
440 }
441 }
442 else
443 {
444 // report DS name error
445 $names = join(",",$heads);
446 $names = str_replace("timestamp,","",$names);
447 warn("RRD ReadData: At least one of your DS names (".$dsnames[IN]." and ".$dsnames[OUT].") were not found, even though there was a valid data line. Maybe they are wrong? Valid DS names in this file are: $names [WMRRD06]\n");
448 }
449 
450 }
451 else
452 {
453 warn("RRD ReadData: failed to open pipe to RRDTool: ".$php_errormsg." [WMRRD04]\n");
454 }
455 debug ("RRD ReadDataFromRealRRD: Returning (".($data[IN]===NULL?'NULL':$data[IN]).",".($data[OUT]===NULL?'NULL':$data[OUT]).",$data_time)\n");
456 }
457 
4581simandl // Actually read data from a data source, and return it
459 // returns a 3-part array (invalue, outvalue and datavalid time_t)
460 // invalue and outvalue should be -1,-1 if there is no valid data
461 // data_time is intended to allow more informed graphing in the future
462 function ReadData($targetstring, &$map, &$item)
463 {
46485simandl global $config;
465 
466 $dsnames[IN] = "traffic_in";
467 $dsnames[OUT] = "traffic_out";
468 $data[IN] = NULL;
469 $data[OUT] = NULL;
470 $SQL[IN] = 'select null';
471 $SQL[OUT] = 'select null';
4721simandl $rrdfile = $targetstring;
473 
47485simandl if($map->get_hint("rrd_default_in_ds") != '') {
475 $dsnames[IN] = $map->get_hint("rrd_default_in_ds");
476 debug("Default 'in' DS name changed to ".$dsnames[IN].".\n");
477 }
478 if($map->get_hint("rrd_default_out_ds") != '') {
479 $dsnames[OUT] = $map->get_hint("rrd_default_out_ds");
480 debug("Default 'out' DS name changed to ".$dsnames[OUT].".\n");
481 }
4821simandl 
48385simandl $multiplier = 8; // default bytes-to-bits
484 
485 $inbw = NULL;
486 $outbw = NULL;
4871simandl $data_time = 0;
488 
489 if(preg_match("/^(.*\.rrd):([\-a-zA-Z0-9_]+):([\-a-zA-Z0-9_]+)$/",$targetstring,$matches))
490 {
491 $rrdfile = $matches[1];
49285simandl 
493 $dsnames[IN] = $matches[2];
494 $dsnames[OUT] = $matches[3];
495 
496 debug("Special DS names seen (".$dsnames[IN]." and ".$dsnames[OUT].").\n");
4971simandl }
498 
499 if(preg_match("/^rrd:(.*)/",$rrdfile,$matches))
500 {
501 $rrdfile = $matches[1];
502 }
503 
504 if(preg_match("/^gauge:(.*)/",$rrdfile,$matches))
505 {
506 $rrdfile = $matches[1];
507 $multiplier = 1;
508 }
509 
51085simandl if(preg_match("/^scale:([+-]?\d*\.?\d*):(.*)/",$rrdfile,$matches))
511 {
512 $rrdfile = $matches[2];
513 $multiplier = $matches[1];
514 }
5151simandl 
51685simandl debug("SCALING result by $multiplier\n");
517 
518 // try and make a complete path, if we've been given a clue
519 // (if the path starts with a . or a / then assume the user knows what they are doing)
520 if(!preg_match("/^(\/|\.)/",$rrdfile))
521 {
522 $rrdbase = $map->get_hint('rrd_default_path');
523 if($rrdbase != '')
524 {
525 $rrdfile = $rrdbase."/".$rrdfile;
526 }
527 }
5281simandl 
52985simandl $cfname = intval($map->get_hint('rrd_cf'));
530 if($cfname=='') $cfname='AVERAGE';
531 
532 $period = intval($map->get_hint('rrd_period'));
533 if($period == 0) $period = 800;
534 $start = $map->get_hint('rrd_start');
535 if($start == '') {
536 $start = "now-$period";
537 $end = "now";
538 }
539 else
540 {
541 $end = "start+".$period;
542 }
5431simandl 
54485simandl $use_poller_output = intval($map->get_hint('rrd_use_poller_output'));
545 $nowarn_po_agg = intval($map->get_hint("nowarn_rrd_poller_output_aggregation"));
546 $aggregatefunction = $map->get_hint('rrd_aggregate_function');
547 
548 if($aggregatefunction != '' && $use_poller_output==1)
549 {
550 $use_poller_output=0;
551 if($nowarn_po_agg==0)
552 {
553 warn("Can't use poller_output for rrd-aggregated data - disabling rrd_use_poller_output [WMRRD10]\n");
554 }
555 }
556 
557 if($use_poller_output == 1)
5581simandl {
55985simandl debug("Going to try poller_output, as requested.\n");
560 WeatherMapDataSource_rrd::wmrrd_read_from_poller_output($rrdfile,"AVERAGE",$start,$end, $dsnames, $data,$map, $data_time,$item);
561 }
562 
563 // if poller_output didn't get anything, or if it couldn't/didn't run, do it the old-fashioned way
564 // - this will still be the case for the first couple of runs after enabling poller_output support
565 // because there won't be valid data in the weathermap_data table yet.
566 if( ($dsnames[IN]!='-' && $data[IN] === NULL) || ($dsnames[OUT] !='-' && $data[OUT] === NULL) )
567 {
568 if($use_poller_output == 1)
5691simandl {
57085simandl debug("poller_output didn't get anything useful. Kicking it old skool.\n");
571 }
572 if(file_exists($rrdfile))
573 {
574 debug ("RRD ReadData: Target DS names are ".$dsnames[IN]." and ".$dsnames[OUT]."\n");
575 
576 $values=array();
577 
578 if ((1==0) && extension_loaded('RRDTool')) // fetch the values via the RRDtool Extension
5791simandl {
58085simandl WeatherMapDataSource_rrd::wmrrd_read_from_php_rrd($rrdfile,$cfname,$start,$end, $dsnames, $data,$map, $data_time,$item);
5811simandl }
582 else
583 {
58485simandl if($aggregatefunction != '')
5851simandl {
58685simandl WeatherMapDataSource_rrd::wmrrd_read_from_real_rrdtool_aggregate($rrdfile,$cfname,$aggregatefunction, $start,$end, $dsnames, $data,$map, $data_time,$item);
5871simandl }
588 else
589 {
59085simandl // do this the tried and trusted old-fashioned way
591 WeatherMapDataSource_rrd::wmrrd_read_from_real_rrdtool($rrdfile,$cfname,$start,$end, $dsnames, $data,$map, $data_time,$item);
5921simandl }
593 }
594 }
59585simandl else
596 {
597 warn ("Target $rrdfile doesn't exist. Is it a file? [WMRRD06]\n");
598 }
5991simandl }
600 
60185simandl // if the Locale says that , is the decimal point, then rrdtool
602 // will honour it. However, floatval() doesn't, so let's replace
603 // any , with . (there are never thousands separators, luckily)
604 //
605 if($data[IN] !== NULL)
606 {
607 $data[IN] = floatval(str_replace(",",".",$data[IN]));
608 $data[IN] = $data[IN] * $multiplier;
609 }
610 if($data[OUT] !== NULL)
611 {
612 $data[OUT] = floatval(str_replace(",",".",$data[OUT]));
613 $data[OUT] = $data[OUT] * $multiplier;
614 }
615 
616 debug ("RRD ReadData: Returning (".($data[IN]===NULL?'NULL':$data[IN]).",".($data[OUT]===NULL?'NULL':$data[OUT]).",$data_time)\n");
617 
618 return( array($data[IN], $data[OUT], $data_time) );
6191simandl }
620}
621 
622// vim:ts=4:sw=4:
623?>

Powered by WebSVN 2.2.1