File:
1.01.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['phpscan']=false;
37: $nodeCfg['phpscandir']="site/";
38:
39: $nodeCfg['xmlscan']=false;
40: $nodeCfg['xmlscandir']="xml/";
41:
42: $nodeCfg['version']="0.04";
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: $mount=$parts[5];
247:
248: //$nicefs=str_replace("/","_",$filesystem);
249: $name=$filesystem.".size";
250: $desc="Total Size of ".$filesystem." (".$mount.") (Mb)";
251: $Node->AddTest($name,$desc,round($size,2),0);
252:
253: $name=$filesystem.".used";
254: $desc="Space Used on ".$filesystem." (".$mount.") (Mb)";
255: $Node->AddTest($name,$desc,round($used,2),0);
256:
257: $name=$filesystem.".free";
258: $desc="Space Free on ".$filesystem." (".$mount.") (Mb)";
259: $Node->AddTest($name,$desc,round($free,2),0);
260:
261: $name=$filesystem.".perc";
262: $desc="Percentage Used on ".$filesystem." (".$mount.")";
263: $Node->AddTest($name,$desc,$perc,0);
264: }
265: }
266: }
267:
268:
269:
270: // ------------------ RAM
271: // Data from FREE
272: if ($nodeCfg['memory'])
273: {
274:
275:
276: $free=array();
277: exec("/usr/bin/free",$free);
278:
279: //unset($this->mm_elements);
280:
281: for ($fc=1; $fc< count($free); $fc++)
282: {
283: // Mem: Swap: -- total, used, free -- kb
284: $parts=preg_split("/\s+/",$free[$fc]);
285: $proc=false;
286: if ($parts[0]=="Mem:") { $proc=true; $type="System Memory"; $prefix="mem"; }
287: else if ($parts[0]=="Swap:") { $proc=true; $type="System Swap File"; $prefix="swap"; }
288: /*
289: else
290: {
291: echo $free[$fc]."\n";
292: exit();
293: }*/
294:
295: if ($proc)
296: {
297: $total=round($parts[1]/1024,3);
298: $usedmb=round($parts[2]/1024,3);
299: $freemb=round($parts[3]/1024,3);
300: $used_perc=0;
301: $free_perc=0;
302: if ($total>0)
303: {
304: if ($used>0) $used_perc=round (($usedmb/$total)*100,2);
305: if ($free>0) $free_perc=round (($freemb/$total)*100,2);
306: }
307: $name=$prefix.".total";
308: $Node->AddTest($name,$type." Total (Mb)",$total,0);
309:
310:
311: $name=$prefix.".used"; // parts[2] used kb
312: $Node->AddTest($name,$type." Used (Mb)",$usedmb,0);
313:
314: $name=$prefix.".free"; // parts[3] free kb
315: $Node->AddTest($name,$type." Free (Mb)",$freemb,0);
316:
317: $name=$prefix.".free.perc";
318: $Node->AddTest($name,$type." Free (%)",$free_perc,0);
319:
320: $name=$prefix.".used.perc";
321: $Node->AddTest($name,$type." Used (%)",$used_perc,0);
322: } // end of if $proc
323:
324: } // end of for
325:
326: }
327:
328:
329:
330: // ------------------ NETWORK USAGE
331: // Data from /proc/net/dev
332: if ($nodeCfg['net'])
333: {
334: $netarr=@file("/proc/net/dev");
335: for($a=2; $a336: {
337: $line=explode(":",$netarr[$a]);
338: $dev=trim($line[0]);
339: $data=trim($line[1]);
340: $darr=preg_split("/[\s]+/",$data);
341: //print_r($darr);
342: //exit();
343: $rx=trim($darr[0]);
344: $tx=trim($darr[8]);
345: if ($rx=="") $rx=0; // bodge
346: if ($tx=="") $tx=0;
347: $tt=$tx+$rx;
348:
349: $Node->AddTest("net.".$dev.".rxt","Total Received on Interface ".$dev." (bytes)",$rx,0);
350: $Node->AddTest("net.".$dev.".txt","Total Sent on Interface ".$dev." (bytes)",$tx,0);
351: $Node->AddTest("net.".$dev.".trt","Total Passed on Interface ".$dev." (bytes)",$tt,0);
352:
353: $trrx=0;
354: $trtx=0;
355: $trtt=0;
356: $trlvl=0;
357:
358: $nowx=time();
359: // does the file exist
360: $fp=fopen($nodeCfg['tmp_dir']."fnnode.net.".$dev,"r");
361: if ($fp>0) // yes
362: {
363: $lastx=trim(fgets($fp,128));
364: $lrx=trim(fgets($fp,128));
365: $ltx=trim(fgets($fp,128));
366: $ltt=$lrx+$ltx;
367: // wrap checking and the like...
368: if ( ($lrx>$rx) ) //|| ($ltx>$tx) || ($ltt>$tt) )
369: {
370: $trlvl=-1; // untested
371: $diffx=0;
372: //echo "untested ".trim($lrx)."-$rx";
373: }
374: else // test it
375: {
376: $diffx=$nowx-$lastx;
377: if ($diffx>0)
378: {
379: $trrx=(($rx-$lrx)/$diffx)/1024;
380: $trtx=(($tx-$ltx)/$diffx)/1024;
381: $trtt=(($tt-$ltt)/$diffx)/1024;
382: }
383: if($trrx=="") $trrx=0;
384: if($trtx=="") $trtx=0;
385: if($trtt=="") $trtt=0;
386: }
387: }
388: else $trlvl=-1;
389: @fclose($fp);
390:
391: // write my file
392: if ($fileUpdate)
393: {
394: //echo "Writing Files!\n";
395: $fp=fopen($nodeCfg['tmp_dir']."fnnode.net.".$dev,"w");
396: fputs($fp,$nowx."\n");
397: fputs($fp,$rx."\n");
398: fputs($fp,$tx."\n");
399: fclose($fp);
400: }
401:
402: $Node->AddTest("net.".$dev.".rx","Receive Speed on ".$dev." (kbyte/s)",$trrx,$trlvl);
403: $Node->AddTest("net.".$dev.".tx","Transmit Speed on ".$dev." (kbyte/s)",$trtx,$trlvl);
404: $Node->AddTest("net.".$dev,"Combined Speed on ".$dev." (kbyte/s)",$trtt,$trlvl);
405: $Node->AddTest("net.".$dev.".elapsed","Speed Sample Time on ".$dev." (secs)",$diffx,$trlvl);
406: }
407: }
408:
409: // ------------------ PROCESS INFORMATION
410: if ($nodeCfg['process'])
411: {
412: $ps=array();
413: exec("/bin/ps -e -w",$ps);
414:
415: $pdata=array();
416: //foreach($ps as $psl)
417: for ($z=1; $z418: {
419: $psl=$ps[$z];
420: $lineparts=preg_split("/\s+/",$psl);
421: $parts=array();
422: for ($a=0; $a423: {
424: if ($lineparts[$a]!="") $parts[]=$lineparts[$a];
425: }
426: //echo $psl."\n";
427: // pid pts time name
428: //echo "[".$parts[0]."] ";
429: //echo "[".$parts[1]."] ";
430: //echo "[".$parts[2]."] ";
431: //echo "[".$parts[3]."]\n";
432:
433: $pname=$parts[3];
434: if (isset($pdata[$pname])) $pdata[$pname]++;
435: else $pdata[$pname]=1;
436: }
437:
438: foreach($pdata as $key=>$val)
439: {
440: $Node->AddTest("ps.".$key,"Number of ".$key." Processes",$val,0);
441: }
442: }
443:
444:
445: // ------------------ END OF TEST DATA
446:
447:
448: // End FreeNATS Data
449: $Node->Stop();
450:
451: if ($pull)
452: {
453: // Output Data to Screen
454: $Node->ScreenOutput();
455: }
456: else // push
457: {
458: // PHP 5 Required
459: $data=array( "nodeid" => $nodeCfg['nodeid'],
460: "nodekey" => $nodeCfg['nodekey'],
461: "xml" => $Node->xml );
462: $data=http_build_query($data);
463:
464: $request=array( "http" => array( "method" => "POST",
465: "header" => "Content-type: application/x-www-form-urlencoded", "content" => $data ) );
466: $context=stream_context_create($request);
467: $fp=fopen($nodeCfg['push_target'],'rb',false,$context);
468: if ($fp<=0)
469: {
470: echo "Push Failed to open URL\n";
471: exit();
472: }
473: $serverdata=@stream_get_contents($fp);
474:
475: if ($serverdata===false)
476: {
477: echo "Push Data is FALSE\n";
478: exit();
479: }
480:
481: if ($serverdata!="1")
482: {
483: echo "Server Returned Error: ".$serverdata."\n";
484: exit();
485: }
486:
487: echo "Push Succeeded\n";
488: }
489:
490: ?>
491: