#!perl
# Script to aggregate some statistics about the processes running on the
# machine. One report groups by user and the other groups by process name.
# This works in Linux, Mac OS, and probably some BSDs.
# Sun's ps command is different.
# Created 03-2006 by Andrew Greenburg <andrew@analogmarketing.net>.
 
use strict;
 
my %uprocesses;     # Number of processes per user
my %ucpupct;        # % CPU usage per user
my %umempct;        # % Memory usage per user
my %umemvsz;        # Total VSZ per user
my %umemrss;        # Total RSS per user
 
my %cprocesses;     # Number of processes per process name
my %ccpupct;        # % CPU usage per process name
my %cmempct;        # % Memory usage per process name
my %cmemvsz;        # Total VSZ per process name
my %cmemrss;        # Total RSS per process name
 
# We hope that ps auwwx looks like this:
# USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COMMAND
# root         1  0.0  0.0  1380  444 ?        S    Mar22   0:05 init
my @processes;
@processes = `ps auwwx`;
shift(@processes);
 
foreach my $psline ( @processes )
{
    my @psinfo;
 
    chomp($psline);
    @psinfo = split(/ +/, $psline);
    $uprocesses{$psinfo[0]} += 1;
    $ucpupct{$psinfo[0]} += $psinfo[2];
    $umempct{$psinfo[0]} += abs($psinfo[3]);   # Sometimes this is negative
    $umemvsz{$psinfo[0]} += $psinfo[4] / 1024; # We want MB, not kB
    $umemrss{$psinfo[0]} += $psinfo[5] / 1024;
 
    # Ignore Linux kernel processes.
    if ( !( $psinfo[10] =~ /^\[/ ) )
    {
        $cprocesses{$psinfo[10]} += 1;
        $ccpupct{$psinfo[10]} += $psinfo[2];
        $cmempct{$psinfo[10]} += abs($psinfo[3]);
        $cmemvsz{$psinfo[10]} += $psinfo[4] / 1024;
        $cmemrss{$psinfo[10]} += $psinfo[5] / 1024;
    }
}
 
print "USER STATS:\n";
print "USER                                 PROCESSES  \%CPU  \%MEM       VSZ       RSS\n";
 
# Cycle through the user hash
foreach my $key ( keys %ucpupct )
{
    printf("%-35.35s  %9d  %4.1f  %4.1f  %7.2fM  %7.2fM\n", $key, $uprocesses{$key}, $ucpupct{$key}, $umempct{$key}, $umemvsz{$key}, $umemrss{$key});
}
 
print "\nCOMMAND STATS:\n";
print "COMMAND                              PROCESSES  \%CPU  \%MEM       VSZ       RSS\n";
 
# Cycle through the process name hash
foreach my $key ( keys %ccpupct )
{
    printf("%-35.35s  %9d  %4.1f  %4.1f  %7.2fM  %7.2fM\n", $key, $cprocesses{$key}, $ccpupct{$key}, $cmempct{$key}, $cmemvsz{$key}, $cmemrss{$key});
}
 
exit(0);