weathermap |
Subversion Repositories: |
Line No. | Rev | Author | Line |
---|---|---|---|
1 | 85 | simandl | <?php |
2 | // Pluggable datasource for PHP Weathermap 0.9 |
||
3 | // - return a live ping result |
||
4 | |
||
5 | // TARGET fping:ipaddress |
||
6 | // TARGET fping:hostname |
||
7 | |
||
8 | class WeatherMapDataSource_fping extends WeatherMapDataSource { |
||
9 | |
||
10 | var $addresscache = array(); |
||
11 | var $donepings = FALSE; |
||
12 | var $results = array(); |
||
13 | |
||
14 | function Init(&$map) |
||
15 | { |
||
16 | # |
||
17 | # You may need to change the line below to have something like "/usr/local/bin/fping" or "/usr/bin/fping" instead. |
||
18 | # |
||
19 | $this->fping_cmd = "/usr/local/sbin/fping"; |
||
20 | |
||
21 | return(TRUE); |
||
22 | } |
||
23 | |
||
24 | // this function will get called for every datasource, even if we replied FALSE to Init. |
||
25 | // (so that we can warn the user that it *would* have worked, if only the plugin could run) |
||
26 | // SO... don't do anything in here that relies on the things that Init looked for, because they might not exist! |
||
27 | function Recognise($targetstring) |
||
28 | { |
||
29 | if(preg_match("/^fping:(\S+)$/",$targetstring,$matches)) |
||
30 | { |
||
31 | // save the address. This way, we can do ONE fping call for all the pings in the map. |
||
32 | // fping does it all in parallel, so 10 hosts takes the same time as 1 |
||
33 | $this->addresscache[]=$matches[1]; |
||
34 | return TRUE; |
||
35 | } |
||
36 | else |
||
37 | { |
||
38 | return FALSE; |
||
39 | } |
||
40 | } |
||
41 | |
||
42 | function ReadData($targetstring, &$map, &$item) |
||
43 | { |
||
44 | $data[IN] = NULL; |
||
45 | $data[OUT] = NULL; |
||
46 | $data_time = 0; |
||
47 | |
||
48 | #debug("-------------------------\n"); |
||
49 | #print_r($this->addresscache); |
||
50 | #debug("-------------------------\n"); |
||
51 | |
||
52 | $ping_count = intval($map->get_hint("fping_ping_count")); |
||
53 | if($ping_count==0) $ping_count = 5; |
||
54 | |
||
55 | if(preg_match("/^fping:(\S+)$/",$targetstring,$matches)) |
||
56 | { |
||
57 | $target = $matches[1]; |
||
58 | |
||
59 | $pattern = "/^$target\s:"; |
||
60 | for($i=0;$i<$ping_count;$i++) $pattern .= "\s(\S+)"; |
||
61 | $pattern .= "/"; |
||
62 | |
||
63 | if(is_executable($this->fping_cmd)) |
||
64 | { |
||
65 | $command = $this->fping_cmd." -t100 -r1 -p20 -u -C $ping_count -i10 -q $target 2>&1"; |
||
66 | debug("Running $command\n"); |
||
67 | $pipe=popen($command, "r"); |
||
68 | |
||
69 | $count = 0; $hitcount=0; |
||
70 | if (isset($pipe)) |
||
71 | { |
||
72 | while (!feof($pipe)) |
||
73 | { |
||
74 | $line=fgets($pipe, 4096); |
||
75 | $count++; |
||
76 | debug("Output: $line"); |
||
77 | |
||
78 | if(preg_match($pattern, $line, $matches)) |
||
79 | { |
||
80 | debug("Found output line for $target\n"); |
||
81 | $hitcount++; |
||
82 | $loss = 0; |
||
83 | $ave = 0; |
||
84 | $total = 0; |
||
85 | $cnt = 0; |
||
86 | $min = 999999; |
||
87 | $max = 0; |
||
88 | for($i=1;$i<=$ping_count;$i++) |
||
89 | { |
||
90 | if($matches[$i]=='-') |
||
91 | { $loss+=(100/$ping_count); } |
||
92 | else |
||
93 | { |
||
94 | $cnt++; |
||
95 | $total += $matches[$i]; |
||
96 | $max = max($matches[$i],$max); |
||
97 | $min = min($matches[$i],$min); |
||
98 | } |
||
99 | } |
||
100 | if($cnt >0) $ave = $total/$cnt; |
||
101 | |
||
102 | debug("Result: $cnt $min -> $max $ave $loss\n"); |
||
103 | } |
||
104 | } |
||
105 | pclose ($pipe); |
||
106 | if($count==0) |
||
107 | { |
||
108 | warn("FPing ReadData: No lines read. Bad hostname? ($target) [WMFPING03]\n"); |
||
109 | } |
||
110 | else |
||
111 | { |
||
112 | if($hitcount == 0) |
||
113 | { |
||
114 | warn("FPing ReadData: $count lines read. But nothing returned for target??? ($target) Try running with DEBUG to see output. [WMFPING02]\n"); |
||
115 | } |
||
116 | else |
||
117 | { |
||
118 | $data[IN] = $ave; |
||
119 | $data[OUT] = $loss; |
||
120 | $item->add_note("fping_min",$min); |
||
121 | $item->add_note("fping_max",$max); |
||
122 | } |
||
123 | } |
||
124 | } |
||
125 | } |
||
126 | else |
||
127 | { |
||
128 | warn("FPing ReadData: Can't find fping executable. Check path at line 19 of WeatherMapDataSource_fping.php [WMFPING01]\n"); |
||
129 | } |
||
130 | } |
||
131 | |
||
132 | debug ("FPing ReadData: Returning (".($data[IN]===NULL?'NULL':$data[IN]).",".($data[OUT]===NULL?'NULL':$data[OUT]).",$data_time)\n"); |
||
133 | |
||
134 | return( array($data[IN], $data[OUT], $data_time) ); |
||
135 | } |
||
136 | } |
||
137 | |
||
138 | // vim:ts=4:sw=4: |
||
139 | ?> |