<?xml version="1.0" encoding="windows-1252"?>
<node id="86015" title="monitor.pl" created="2001-06-05 21:12:29" updated="2005-08-14 03:50:58">
<type id="1748">
sourcecode</type>
<author id="78015">
xphase_work</author>
<data>
<field name="doctext">
&lt;code&gt;
#################################################
# monitor.pl									#
#		Brian Wilson - 2001						#
#												#
#	A Tk utility that draws a window with 		#
#	Various system information in it.			#
#	Currently shows: OS name and version,		#
#					 Load, Uptime, Processes,	#
#					 Mem/FreeMem, Swap/Free Swap#
#					 And # of Users				#
#	Version 1.0 -- First Release				#
#												#
#################################################
use strict;
use Tk;
use Tk::ProgressBar;

# Declare a window, some frames, and some vars
my $window = MainWindow-&gt;new(-title =&gt; 'System Monitor', -background =&gt; 'black');
my $memUsage;
my $swapUsage;
my ($prog1, $prog2);

my $topFrame= $window-&gt;Frame(-bg=&gt;'black')-&gt;pack(-side =&gt;'top');
my $hiFrame = $window-&gt;Frame(-bg=&gt;'black')-&gt;pack(-side =&gt;'top');
my $loFrame = $window-&gt;Frame(-bg=&gt;'black')-&gt;pack(-side =&gt; 'bottom');
												
my $listf1 = $hiFrame-&gt;Frame(-bg=&gt;'black')-&gt;pack(-side =&gt; 'left');
my $listf2 = $hiFrame-&gt;Frame(-bg=&gt;'black')-&gt;pack(-side =&gt; 'right');

my $progf1 = $loFrame-&gt;Frame(-bg=&gt;'black')-&gt;pack(-side =&gt; 'left');
my $progf2 = $loFrame-&gt;Frame(-bg=&gt;'black')-&gt;pack(-side =&gt; 'right');
my $progf3 = $loFrame-&gt;Frame(-bg=&gt;'black')-&gt;pack(-side =&gt; 'left');

#A text box in the top most frame displays the hostname, OS, and OS Version
my $title = $topFrame-&gt;Text(-width	=&gt; 20,
								 -height=&gt; 1,
								 -bg	=&gt; 'black',
								 -fg	=&gt; 'yellow',
								 -relief=&gt; 'flat',
								 -insertborderwidth=&gt;0,
								 -highlightbackground=&gt; 'black',
								 )-&gt;pack(-side =&gt; 'left');
# Place a Listbox in the left side of the middle frame to use as labels								 
my $labelList = $listf1-&gt;Listbox(-width	=&gt; 15,
								 -height=&gt; 4,
								 -bg	=&gt; 'black',
								 -fg	=&gt; 'yellow',
								 -relief=&gt; 'flat',
								 #-insertborderwidth=&gt;0,
								 -highlightbackground=&gt; 'black',
								 )-&gt;pack(-side =&gt; 'left');
# Fill the Listbox with the labels								
$labelList-&gt;insert('end',
					"System Load:",
					"System Up:",
					"Processes:",
					"Total Users");

# Place a list box in the right side of the middle frame to display data					
my $dataList = $listf2-&gt;Listbox(-width	=&gt; 15,
								 -height=&gt; 4,
								 -bg	=&gt; 'black',
								 -fg	=&gt; 'yellow',
								 -relief=&gt; 'flat',
								 #-insertborderwidth=&gt;0,
								 -highlightbackground=&gt; 'black',
								 )-&gt;pack(-side =&gt; 'left');

# Place a list box in the right side of the bottom left frame for labels								 
my $memLabelList=$progf1-&gt;Listbox(-width=&gt; 15,
								 -height=&gt; 2,
								 -bg	=&gt; 'black',
								 -fg	=&gt; 'yellow',
								 -relief=&gt; 'flat',
								 #-insertborderwidth=&gt;0,
								 -highlightbackground=&gt; 'black',
								 )-&gt;pack(-side =&gt; 'left');
# Fill the list with labels								 
$memLabelList-&gt;insert('end',
						"Memory Used:",
						"Swap Used:");

# Place a Listbox in the bottom right frame for number data						
my $memList = $progf2-&gt;Listbox(-width=&gt; 15,
								 -height=&gt; 2,
								 -bg	=&gt; 'black',
								 -fg	=&gt; 'yellow',
								 -relief=&gt; 'flat',
								 #-insertborderwidth=&gt;0,
								 -highlightbackground=&gt; 'black',
								 )-&gt;pack(-side =&gt; 'right');
								 
# Call the subroutine for the first time
&amp;drawvals;
# Wait 5 seconds then run the subroutine again for ever
$progf3-&gt;repeat(5000,\&amp;drawvals);

# Create a progress bar in the top fo the bottom middle
# frame that shows amount of Used Memory
$prog1 = $progf3 -&gt;ProgressBar(	-relief	=&gt; 'flat',
								-resolution =&gt; 0,
								-gap	=&gt; 0,
								-from	=&gt; 0,
								-to		=&gt; 100,
								-anchor	=&gt; 'e',
								-blocks	=&gt;	10,
								-bg		=&gt; 'black',
								-colors =&gt; [0,'green',50,'yellow',80,'red'],
								-variable=&gt; \$memUsage,
							  )-&gt;pack(-side	=&gt; 'top', -pady =&gt; 3);
							 
# Create a progress bar in the bottom of the bottom middle
# frame to show the amout of Swap Used. 
$prog2 = $progf3 -&gt;ProgressBar(	-relief	=&gt; 'flat',
								-resolution =&gt; 0,
								-gap	=&gt; 0,
								-from	=&gt; 0,
								-to		=&gt; 100,
								-anchor	=&gt; 'e',
								-blocks	=&gt;	10,
								-bg		=&gt; 'black',
								-colors =&gt; [0,'green',50,'yellow',80,'red'],
								-variable=&gt; \$swapUsage,
							  )-&gt;pack(-side	=&gt; 'bottom', -pady =&gt; 3);
							 
# Tk's main event loop
MainLoop;

# This subroutine sets the values for Used Mem and Used Swap,
# as well as clearing and filling in the Listboxes with the
# correct data
sub drawvals{
	my %values = &amp;vals;
	my $useMem = $values{totMem} - $values{freeMem};
	
	$swapUsage = ($values{useSwap}/$values{totSwap})*100;
	$memUsage  = ($useMem/$values{totMem})*100;
	$dataList-&gt;delete('0.0', 'end');
	$title-&gt;delete('0.0', 'end');
	$title-&gt;insert('end',"$values{host} - $values{OS} $values{OSVer}", 'yellow');
	
	$dataList-&gt;insert('end',"$values{load}");
	$dataList-&gt;insert('end',"$values{uptime}");
	$dataList-&gt;insert('end',"$values{process}");
	$dataList-&gt;insert('end',"$values{numUsers}");
	
	$memList-&gt;delete('0.0', 'end');
	$memList-&gt;insert('end', "${useMem}M of $values{totMem}M");
	$memList-&gt;insert('end', "$values{useSwap}M of $values{totSwap}M");
	
	
}
	

# This subroutine gathers the data to be displayed			
sub vals{

	my @top;
	my $proc;
	my @memInfo;
	my ($real, $rFree, $sUse, $sFree);
	my $version;
	my $load;
	my @upArray;
	my @tUp;
	my $uptime;
	my $name; 
	my $line;
	my $t;
	my $user;
	my %unique;
	my @who;  
	my $numUsers;
	my $swap;
	my %vals;

	# Get the version number of the OS, if solaris change the 5 to a 2
	# Also get the hostname using uname -n
	($name, $version) = split ' ',(`uname -nr`);                
	if($^O =~ /solaris/){ ($version eq 5.5.1) ? ($version = 2.5.1)
											  : ($version -= 3)}
	# Run top and collect the output
	@top = `top -n 1 2&gt;/dev/null`;        
	chomp($name);            
	# Get a list of the users
	@who = `who`;                         
    
	# Store users in a hash, might add a listing of users to disp
	# in the future                                 
	foreach $line (@who){                 
		$user = (split ' ', $line)[0];    
                                      
    	if(!$unique{$user}){              
    	    $unique{$user} = 1;           
    	}                                 
   		else {                            
        	$unique{$user}++;             
    	}                                 
	}
	                                     
    # Get uptime and system load from the uptime command                                  
	@upArray =  split ',', `uptime`;      
	$t = `uptime`;                        
	$t =~ /load average.*:\s+(\S+),/;
	$load = $1;
	@tUp = split ' ', $upArray[0];        
	$uptime = "@tUp[scalar(@tUp)-2] @tUp[scalar(@tUp)-1]";

    # Process top to get the number of processes, as well as the Memory
	# and Swap levels                                  
	foreach $line (@top){                 

    	if($line =~ /\d*?\sprocesses/){   
       		$proc = (split ' ', $line)[0];
    	}
    	elsif($line =~ /^Memory/i){       
        	($t, $line) = split ':', $line;
        	@memInfo = split ',', $line;  
        
        	$real = $memInfo[0];          
        	$real =~ s/^\s*(\d+[KM]).*$/$1/;
        	$real =~ s/[MK]//g;           
                                      
        	$rFree = $memInfo[1];
        	if($rFree =~ /\dK/i){         
            	$rFree =~ s/^\s*(\d+[KM]).*$/$1/;
            	$rFree =~ s/[MK]//g;  
				$rFree = int($rFree/1024);
        	} 
        	else {
            	$rFree =~ s/^\s*(\d+[KM]).*$/$1/;
            	$rFree =~ s/[MK]//g;      
        	}
    
        	$sUse = $memInfo[2];
        	if($sUse =~ /\d+K/i){
            	$sUse =~ s/^\s*(\d+[KM]).*$/$1/;
            	$sUse =~ s/[MK]//g;
            	$sUse = int($sUse/1024);  
        	}
        	else {
            	$sUse =~ s/^\s*(\d+[KM]).*$/$1/;
            	$sUse =~ s/[MK]//g;       
        	}                             
        
        	chomp($sFree = $memInfo[3]);         
        	if($sFree =~ /\d+K/i){
            	$sFree =~ s/^\s*(\d+[KM]).*$/$1/;
				$sFree =~ s/[MK]//g;
            	$sFree = int($sFree/1024);
        	}
        	else {
            	$sFree =~ s/^\s*(\d+[KM]).*$/$1/;
            	$sFree =~ s/[MK]//g;
        	}
    	}   
	}

	# Count the number of unique users
	# NOTE: This is due to(at least on my workstation at work)
	#		each instance of a term counting as a user in who.
	#		Oddly enough, finger behaves this way at my work as
	#		well, a finger on me produces as many entries as terms
	#		That I have open
	foreach $user(keys %unique){
		$numUsers++;
	}
	$swap = $sUse + $sFree;
	
	# Place the values in a hash
	%vals =(host 	=&gt; $name,
			OS		=&gt; $ ,
			OSVer	=&gt; $version,
			load	=&gt; $load,
			uptime	=&gt; $uptime,
			process	=&gt; $proc,
			totMem	=&gt; $real,
			freeMem	=&gt; $rFree,
			totSwap	=&gt; $swap,
			useSwap	=&gt; $sUse,
			numUsers=&gt; $numUsers,
			);

	return %vals;
}
&lt;/code&gt;</field>
<field name="codedescription">
A simple system monitor written in Tk, should be&lt;br&gt;
cross-platfrom, but only tested on Solaris 2.7.&lt;br&gt;
This is my first somewhat large app in Perl/Tk.&lt;br&gt;
Any comments would be helpful.</field>
<field name="codecategory">
GUI Programming</field>
<field name="codeauthor">
xPhase_work</field>
</data>
</node>
