File:
1.19.1b/node/posix/freenats-node.php (
View as Code)
1: 2: // FreeNATS Push/Pull XML Node for Posix Environments
3: /* -------------------------------------------------------------
4: This file is part of FreeNATS
5:
6: FreeNATS is (C) Copyright 2008-2016 PurplePixie Systems
7:
8: FreeNATS is free software: you can redistribute it and/or modify
9: it under the terms of the GNU General Public License as published by
10: the Free Software Foundation, either version 3 of the License, or
11: (at your option) any later version.
12:
13: FreeNATS is distributed in the hope that it will be useful,
14: but WITHOUT ANY WARRANTY; without even the implied warranty of
15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16: GNU General Public License for more details.
17:
18: You should have received a copy of the GNU General Public License
19: along with FreeNATS. If not, see www.gnu.org/licenses
20:
21: For more information see www.purplepixie.org/freenats
22: -------------------------------------------------------------- */
23:
24: // Configuration Section
25:
26: $nodeCfg=array();
27:
28: $nodeCfg['allowpull']=true;
29: $nodeCfg['allowpush']=true;
30: $nodeCfg['nodekey']="";
31: $nodeCfg['nodeid']="";
32: $nodeCfg['restrict_pull_ip']="";
33: $nodeCfg['push_target']="";
34: $nodeCfg['tmp_dir']="/tmp/";
35:
36: $nodeCfg['phpscan']=false;
37: $nodeCfg['phpscandir']="site/";
38:
39: $nodeCfg['xmlscan']=false;
40: $nodeCfg['xmlscandir']="xml/";
41:
42: $nodeCfg['version']="0.09";
43:
44: $nodeCfg['uptime'] = true;
45: $nodeCfg['disk'] = true;
46: $nodeCfg['memory'] = true;
47: $nodeCfg['net'] = true;
48: $nodeCfg['systime'] = true;
49: $nodeCfg['process'] = true;
50:
51: // End of Configuration Section
52:
53: $configFile="config.inc.php";
54: $fileUpdate=true;
55:
56: $tests=array();
57:
58: // XML Format
59: /*
60: Format:
61:
62: 63: something
64:
65:
66: testname
67: Test Description
68: return value
69: suggested alert level
70:
71:
72: */
73:
74: class FreeNATS_XML_Node
75: {
76: var $xml="";
77: var $Config;
78:
79: function AddLine($line)
80: {
81: $this->xml.=$line."\n";
82: }
83:
84: function AddTest($name,$desc,$val,$lvl=-1)
85: {
86: global $tests;
87: $add=0;
88: $oname=$name;
89: while (isset($tests[$name]))
90: {
91: $name=$oname."-".$add;
92: $add++;
93: }
94: $tests[$name]=1;
95: $this->AddLine("");
96: $this->AddLine(" ");
97: $this->AddLine(" ".$name."");
98: $this->AddLine(" ".$desc."");
99: $this->AddLine(" ".$val."");
100: $this->AddLine(" ".$lvl."");
101: $this->AddLine(" ");
102: $this->AddLine("");
103: }
104:
105: function FreeNATS_XML_Node()
106: {
107: global $nodeCfg;
108: $this->AddLine("");
109: $this->Config=&$nodeCfg;
110: }
111:
112: function Start()
113: {
114: $this->AddLine("");
115: }
116:
117: function Stop()
118: {
119: $this->AddLine("");
120: }
121:
122: function DataHeader($is_header=true)
123: {
124: if ($is_header) $this->AddLine(" 125: else $this->AddLine(" ");
126: }
127:
128: function HeaderItem($name,$value)
129: {
130: $this->AddLine(" <".$name.">".$value."".$name.">");
131: }
132:
133: function ScreenOutput()
134: {
135: header("Content-type: text/xml");
136: echo $this->xml;
137: exit();
138: }
139:
140: }
141:
142: $Node=new FreeNATS_XML_Node();
143: $Node->Start();
144:
145:
146: // How Were We Called
147: $pull=false;
148:
149: if (isset($_SERVER['REMOTE_ADDR'])) // called via HTTP
150: {
151: $pull=true;
152: if ($nodeCfg['restrict_pull_ip']!="") // check IP
153: {
154: if ($_SERVER['REMOTE_ADDR']!=$nodeCfg['restrict_pull_ip'])
155: {
156: echo "Authorisation Failure: IP Address Denied";
157: exit();
158: }
159: }
160: if ($nodeCfg['nodekey']!="") // check authorisation
161: {
162: if ( !(isset($_REQUEST['nodekey'])) || ($_REQUEST['nodekey']!=$nodeCfg['nodekey']) )
163: {
164: echo "Authorisation Failure: Incorrect NODEKEY Configured";
165: exit();
166: }
167: }
168: if (isset($_REQUEST['noupdate']) && ($_REQUEST['noupdate']==1)) $fileUpdate=false;
169: }
170: else // called via CLI
171: {
172: $a=1;
173: for ($a=1; $a<$argc; $a++)
174: {
175: switch($argv[$a])
176: {
177: case "-c": case "--c": case "-config": case "--config":
178: $configFile=$argv[++$a];
179: break;
180: case "-d": case "--d": case "-debug": case "--debug":
181: $pull=true; // output to the console
182: break;
183: case "--noupdate": case "-noupdate":
184: $fileUpdate=false;
185: break;
186: }
187: }
188: }
189:
190: if ($configFile!="") require($configFile);
191:
192:
193: $Node->DataHeader();
194: $Node->HeaderItem("name","FreeNATS Posix Node XML");
195: $Node->HeaderItem("version",$nodeCfg['version']);
196: if (!$pull) // we are pushing instead
197: $Node->HeaderItem("nodekey",$nodeCfg['nodekey']);
198: $Node->DataHeader(false);
199:
200: // Node Type and Version Pseudo-Tests
201: $Node->AddTest("fnn.version","FreeNATS Node Version",$nodeCfg['version'],0);
202: $Node->AddTest("fnn.name","FreeNATS Node Type","Posix XML",0);
203:
204: //$Node->AddTest("bob.one","Bob One",10,0);
205: //$Node->AddTest("bob.two","Bob Two",11,0);
206:
207:
208: // Data from Uptime
209: if ($nodeCfg['uptime'])
210: {
211: $uptime=exec("/usr/bin/uptime");
212:
213: $ut=preg_split("/\s+/",$uptime);
214: //var_dump($ut);
215:
216:
217:
218: $Node->AddTest("uptime.1m","One Minute Load Average",substr($ut[count($ut)-3],0,strlen($ut[count($ut)-3])-1),0);
219: $Node->AddTest("uptime.5m","Five Minute Load Average",substr($ut[count($ut)-2],0,strlen($ut[count($ut)-2])-1),0);
220: $Node->AddTest("uptime.15m","Fifteen Minute Load Average",$ut[count($ut)-1],0);
221: $Node->AddTest("uptime.users","Logged in Users",$ut[count($ut)-7],0);
222: }
223:
224: // Data from Time
225: if ($nodeCfg['systime'])
226: {
227: $nowx=time();
228: $utf=date("Y-m-d H:i:s",$nowx);
229: $dts=date("H:i:s d/m/Y",$nowx);
230: $pasthour= (date("i",$nowx)*60)+date("s",$nowx);
231:
232: $Node->AddTest("systime.x","Node Time (Seconds Since Epoch)",$nowx,0);
233: $Node->AddTest("systime.utf","Node Time (UTF)",$utf,0);
234: $Node->AddTest("systime.dts","Note Time",$dts,0);
235: $Node->AddTest("systime.sph","Seconds Past Hour",$pasthour,0);
236: }
237:
238: // ------------------ DISK SPACE
239:
240: // Data from DF
241: if ($nodeCfg['disk'])
242: {
243: $result=array();
244: exec("/bin/df -P",$result);
245:
246: // filesystem blocks used available use% mount
247: for ($a=1; $a248: {
249: $parts=preg_split("/\s+/",$result[$a]);
250: if (count($parts)>4) // not a duff line
251: {
252: $filesystem=$parts[0];
253: $size=$parts[1]/1024;
254: $used=$parts[2]/1024;
255: $free=$parts[3]/1024;
256: $perc=substr($parts[4],0,(strlen($parts[4])-1));
257: $percfree=100-$perc;
258: $mount=$parts[5];
259:
260: if ($perc >= 90) $alertlevel=2; // failed
261: else if ($perc >= 80) $alertlevel=1; // warning
262: else $alertlevel=0; // passed
263:
264: //$nicefs=str_replace("/","_",$filesystem);
265: $name=$filesystem.".size";
266: $desc="Total Size of ".$filesystem." (".$mount.") (Mb)";
267: $Node->AddTest($name,$desc,round($size,2),$alertlevel);
268:
269: $name=$filesystem.".used";
270: $desc="Space Used on ".$filesystem." (".$mount.") (Mb)";
271: $Node->AddTest($name,$desc,round($used,2),$alertlevel);
272:
273: $name=$filesystem.".free";
274: $desc="Space Free on ".$filesystem." (".$mount.") (Mb)";
275: $Node->AddTest($name,$desc,round($free,2),$alertlevel);
276:
277: $name=$filesystem.".perc";
278: $desc="Percentage Used on ".$filesystem." (".$mount.")";
279: $Node->AddTest($name,$desc,$perc,$alertlevel);
280:
281: $name=$filesystem.".percfree";
282: $desc="Percentage Free on ".$filesystem." (".$mount.")";
283: $Node->AddTest($name,$desc,$percfree,$alertlevel);
284: }
285: }
286: }
287:
288:
289:
290: // ------------------ RAM
291: // Data from FREE
292: if ($nodeCfg['memory'])
293: {
294:
295:
296: $free=array();
297: exec("/usr/bin/free",$free);
298:
299: //unset($this->mm_elements);
300:
301: for ($fc=1; $fc< count($free); $fc++)
302: {
303: // Mem: Swap: -- total, used, free -- kb
304: $parts=preg_split("/\s+/",$free[$fc]);
305: $proc=false;
306: if ($parts[0]=="Mem:") { $proc=true; $type="System Memory"; $prefix="mem"; }
307: else if ($parts[0]=="Swap:") { $proc=true; $type="System Swap File"; $prefix="swap"; }
308: /*
309: else
310: {
311: echo $free[$fc]."\n";
312: exit();
313: }*/
314:
315: if ($proc)
316: {
317: $total=round($parts[1]/1024,3);
318: $usedmb=round($parts[2]/1024,3);
319: $freemb=round($parts[3]/1024,3);
320: $used_perc=0;
321: $free_perc=0;
322: if ($total>0)
323: {
324: if ($used>0) $used_perc=round (($usedmb/$total)*100,2);
325: if ($free>0) $free_perc=round (($freemb/$total)*100,2);
326: }
327: $name=$prefix.".total";
328: $Node->AddTest($name,$type." Total (Mb)",$total,0);
329:
330:
331: $name=$prefix.".used"; // parts[2] used kb
332: $Node->AddTest($name,$type." Used (Mb)",$usedmb,0);
333:
334: $name=$prefix.".free"; // parts[3] free kb
335: $Node->AddTest($name,$type." Free (Mb)",$freemb,0);
336:
337: $name=$prefix.".free.perc";
338: $Node->AddTest($name,$type." Free (%)",$free_perc,0);
339:
340: $name=$prefix.".used.perc";
341: $Node->AddTest($name,$type." Used (%)",$used_perc,0);
342: } // end of if $proc
343:
344: } // end of for
345:
346: }
347:
348:
349:
350: // ------------------ NETWORK USAGE
351: // Data from /proc/net/dev
352: if ($nodeCfg['net'])
353: {
354: $netarr=@file("/proc/net/dev");
355: for($a=2; $a356: {
357: $line=explode(":",$netarr[$a]);
358: $dev=trim($line[0]);
359: $data=trim($line[1]);
360: $darr=preg_split("/[\s]+/",$data);
361: //print_r($darr);
362: //exit();
363: $rx=trim($darr[0]);
364: $tx=trim($darr[8]);
365: if ($rx=="") $rx=0; // bodge
366: if ($tx=="") $tx=0;
367: $tt=$tx+$rx;
368:
369: $Node->AddTest("net.".$dev.".rxt","Total Received on Interface ".$dev." (bytes)",$rx,0);
370: $Node->AddTest("net.".$dev.".txt","Total Sent on Interface ".$dev." (bytes)",$tx,0);
371: $Node->AddTest("net.".$dev.".trt","Total Passed on Interface ".$dev." (bytes)",$tt,0);
372:
373: $trrx=0;
374: $trtx=0;
375: $trtt=0;
376: $trlvl=0;
377:
378: $nowx=time();
379: // does the file exist
380: $fp=fopen($nodeCfg['tmp_dir']."fnnode.net.".$dev,"r");
381: if ($fp>0) // yes
382: {
383: $lastx=trim(fgets($fp,128));
384: $lrx=trim(fgets($fp,128));
385: $ltx=trim(fgets($fp,128));
386: $ltt=$lrx+$ltx;
387: // wrap checking and the like...
388: if ( ($lrx>$rx) ) //|| ($ltx>$tx) || ($ltt>$tt) )
389: {
390: $trlvl=-1; // untested
391: $diffx=0;
392: //echo "untested ".trim($lrx)."-$rx";
393: }
394: else // test it
395: {
396: $diffx=$nowx-$lastx;
397: if ($diffx>0)
398: {
399: $trrx=(($rx-$lrx)/$diffx)/1024;
400: $trtx=(($tx-$ltx)/$diffx)/1024;
401: $trtt=(($tt-$ltt)/$diffx)/1024;
402: }
403: if($trrx=="") $trrx=0;
404: if($trtx=="") $trtx=0;
405: if($trtt=="") $trtt=0;
406: }
407: }
408: else $trlvl=-1;
409: @fclose($fp);
410:
411: // write my file
412: if ($fileUpdate)
413: {
414: //echo "Writing Files!\n";
415: $fp=fopen($nodeCfg['tmp_dir']."fnnode.net.".$dev,"w");
416: fputs($fp,$nowx."\n");
417: fputs($fp,$rx."\n");
418: fputs($fp,$tx."\n");
419: fclose($fp);
420: }
421:
422: $Node->AddTest("net.".$dev.".rx","Receive Speed on ".$dev." (kbyte/s)",$trrx,$trlvl);
423: $Node->AddTest("net.".$dev.".tx","Transmit Speed on ".$dev." (kbyte/s)",$trtx,$trlvl);
424: $Node->AddTest("net.".$dev,"Combined Speed on ".$dev." (kbyte/s)",$trtt,$trlvl);
425: $Node->AddTest("net.".$dev.".elapsed","Speed Sample Time on ".$dev." (secs)",$diffx,$trlvl);
426: }
427: }
428:
429: // ------------------ PROCESS INFORMATION
430: if ($nodeCfg['process'])
431: {
432: $ps=array();
433: exec("/bin/ps -e -w",$ps);
434:
435: $pdata=array();
436: //foreach($ps as $psl)
437: for ($z=1; $z438: {
439: $psl=$ps[$z];
440: $lineparts=preg_split("/\s+/",$psl);
441: $parts=array();
442: for ($a=0; $a443: {
444: if ($lineparts[$a]!="") $parts[]=$lineparts[$a];
445: }
446: //echo $psl."\n";
447: // pid pts time name
448: //echo "[".$parts[0]."] ";
449: //echo "[".$parts[1]."] ";
450: //echo "[".$parts[2]."] ";
451: //echo "[".$parts[3]."]\n";
452:
453: $pname=$parts[3];
454: if (isset($pdata[$pname])) $pdata[$pname]++;
455: else $pdata[$pname]=1;
456: }
457:
458: foreach($pdata as $key=>$val)
459: {
460: $Node->AddTest("ps.".$key,"Number of ".$key." Processes",$val,0);
461: }
462: }
463:
464:
465: // ------------------ END OF TEST DATA
466:
467:
468: // End FreeNATS Data
469: $Node->Stop();
470:
471: if ($pull)
472: {
473: // Output Data to Screen
474: $Node->ScreenOutput();
475: }
476: else // push
477: {
478: // PHP 5 Required
479: $data=array( "nodeid" => $nodeCfg['nodeid'],
480: "nodekey" => $nodeCfg['nodekey'],
481: "xml" => $Node->xml );
482: $data=http_build_query($data);
483:
484: $request=array( "http" => array( "method" => "POST",
485: "header" => "Content-type: application/x-www-form-urlencoded", "content" => $data ) );
486: $context=stream_context_create($request);
487: $fp=fopen($nodeCfg['push_target'],'rb',false,$context);
488: if ($fp<=0)
489: {
490: echo "Push Failed to open URL\n";
491: exit();
492: }
493: $serverdata=@stream_get_contents($fp);
494:
495: if ($serverdata===false)
496: {
497: echo "Push Data is FALSE\n";
498: exit();
499: }
500:
501: if ($serverdata!="1")
502: {
503: echo "Server Returned Error: ".$serverdata."\n";
504: exit();
505: }
506:
507: echo "Push Succeeded\n";
508: }
509:
510: ?>
511: