File: 1.19.1b/node/posix/freenats-node.php (View as HTML)

  1: <?php // freenats-node.php
  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: <freenats-data>
 62:  <header>
 63:   <whatever>something</whatever>
 64:  </header>
 65:  <test name=testname>
 66:   <name>testname</name>
 67:   <desc>Test Description</desc>
 68:   <value>return value</value>
 69:   <alertlevel>suggested alert level</alertlevel>
 70:  </test>
 71: </freenats-data>
 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(" <test NAME=\"".$name."\">");
 97: 	$this->AddLine("  <name>".$name."</name>");
 98: 	$this->AddLine("  <desc>".$desc."</desc>");
 99: 	$this->AddLine("  <value>".$val."</value>");
100: 	$this->AddLine("  <alertlevel>".$lvl."</alertlevel>");
101: 	$this->AddLine(" </test>");
102: 	$this->AddLine("");
103: }
104: 
105: function FreeNATS_XML_Node()
106: {
107: global $nodeCfg;
108: $this->AddLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
109: $this->Config=&$nodeCfg;
110: }
111: 
112: function Start()
113: {
114: $this->AddLine("<freenats-data>");
115: }
116: 
117: function Stop()
118: {
119: $this->AddLine("</freenats-data>");
120: }
121: 
122: function DataHeader($is_header=true)
123: {
124: if ($is_header) $this->AddLine(" <header>");
125: else $this->AddLine(" </header>");
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; $a<count($result); $a++)
248:    {
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; $a<count($netarr); $a++)
356: 	{
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; $z<count($ps); $z++)
438: 		{
439: 		$psl=$ps[$z];
440: 		$lineparts=preg_split("/\s+/",$psl);
441: 		$parts=array();
442: 		for ($a=0; $a<count($lineparts); $a++)
443: 			{
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: