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