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