jablonka.czprosek.czf

weathermap

Subversion Repositories:
[/] [lib/] [datasources/] [WeatherMapDataSource_fping.php] - Rev 108 Go to most recent revision

Compare with Previous - Blame - Download


<?php
// Pluggable datasource for PHP Weathermap 0.9
// - return a live ping result

// TARGET fping:ipaddress
// TARGET fping:hostname

class WeatherMapDataSource_fping extends WeatherMapDataSource {

        var $addresscache = array();
        var $donepings = FALSE;
        var $results = array();

        function Init(&$map)
        {
                # 
                # You may need to change the line below to have something like "/usr/local/bin/fping" or "/usr/bin/fping" instead.
                #
                $this->fping_cmd = "/usr/local/sbin/fping";
        
                return(TRUE);
        }

        // this function will get called for every datasource, even if we replied FALSE to Init.
        // (so that we can warn the user that it *would* have worked, if only the plugin could run)
        // SO... don't do anything in here that relies on the things that Init looked for, because they might not exist!
        function Recognise($targetstring)
        {
                if(preg_match("/^fping:(\S+)$/",$targetstring,$matches))
                {
                        // save the address. This way, we can do ONE fping call for all the pings in the map.
                        // fping does it all in parallel, so 10 hosts takes the same time as 1
                        $this->addresscache[]=$matches[1];
                        return TRUE;
                }
                else
                {
                        return FALSE;
                }
        }

        function ReadData($targetstring, &$map, &$item)
        {
                $data[IN] = NULL;
                $data[OUT] = NULL;
                $data_time = 0;

                #debug("-------------------------\n");
                #print_r($this->addresscache);
                #debug("-------------------------\n");
                
                $ping_count = intval($map->get_hint("fping_ping_count"));
                if($ping_count==0) $ping_count = 5;             
                
                if(preg_match("/^fping:(\S+)$/",$targetstring,$matches))
                {
                        $target = $matches[1];
                        
                        $pattern = "/^$target\s:";
                        for($i=0;$i<$ping_count;$i++) $pattern .= "\s(\S+)";
                        $pattern .= "/";
                        
                        if(is_executable($this->fping_cmd))
                        {
                                $command = $this->fping_cmd." -t100 -r1 -p20 -u -C $ping_count -i10 -q $target 2>&1";
                                debug("Running $command\n");
                                $pipe=popen($command, "r");
                                                
                                $count = 0; $hitcount=0;
                                if (isset($pipe))
                                {
                                        while (!feof($pipe))
                                        {
                                                $line=fgets($pipe, 4096);
                                                $count++;
                                                debug("Output: $line");
                                                
                                                if(preg_match($pattern, $line, $matches))
                                                {
                                                        debug("Found output line for $target\n");
                                                        $hitcount++;
                                                        $loss = 0;
                                                        $ave = 0;
                                                        $total = 0;
                                                        $cnt = 0;
                                                        $min = 999999;
                                                        $max = 0;
                                                        for($i=1;$i<=$ping_count;$i++)
                                                        {
                                                                if($matches[$i]=='-') 
                                                                { $loss+=(100/$ping_count); }
                                                                else
                                                                {
                                                                        $cnt++;
                                                                        $total += $matches[$i];
                                                                        $max = max($matches[$i],$max);
                                                                        $min = min($matches[$i],$min);
                                                                }
                                                        }
                                                        if($cnt >0) $ave = $total/$cnt;
                                                        
                                                        debug("Result: $cnt $min -> $max $ave $loss\n");
                                                }
                                        }
                                        pclose ($pipe);
                                        if($count==0)
                                        {
                                                warn("FPing ReadData: No lines read. Bad hostname? ($target) [WMFPING03]\n");
                                        }
                                        else
                                        {
                                                if($hitcount == 0)
                                                {
                                                        warn("FPing ReadData: $count lines read. But nothing returned for target??? ($target) Try running with DEBUG to see output.  [WMFPING02]\n");
                                                }
                                                else
                                                {
                                                        $data[IN] = $ave;
                                                        $data[OUT] = $loss;
                                                        $item->add_note("fping_min",$min);
                                                        $item->add_note("fping_max",$max);
                                                }
                                        }
                                }
                        }
                        else
                        {
                                warn("FPing ReadData: Can't find fping executable. Check path at line 19 of WeatherMapDataSource_fping.php [WMFPING01]\n");
                        }
                }

                debug ("FPing ReadData: Returning (".($data[IN]===NULL?'NULL':$data[IN]).",".($data[OUT]===NULL?'NULL':$data[OUT]).",$data_time)\n");
                
                return( array($data[IN], $data[OUT], $data_time) );
        }
}

// vim:ts=4:sw=4:
?>

Powered by WebSVN 2.2.1