dark

Monitor resources on a UNIX machine (with Perl)

blank

To get an overview of what is running on a certain UNIX/Linux host, most users will usually run of one the following commands:

  • ps
  • top
  • htop

But most of the times, they will not give a correct view of what is really going on, and most of the times we want to see totals instead of individual processes with their resource consumption.


Since Perl is one of the default scripting languages on almost every UNIX/Linux flavour, we will use this language to create a script which will allow us to get general overview of how much an application is really using up (all childs processes, threads, …).

The script uses two functions:

  • get_proc_list()
  • print_sorted()
sub get_proc_list {
    my($ps_fields, $key) = @_;

    my $ps_cmd = "ps -T -e -o $ps_fields,$DEFAULT_FIELDS --sort $ps_fields";
    my @process_list = do {
        open my $cmd, '-|', $ps_cmd or die "Kak: $!n";
        <$cmd>;
    };

    my %top_res;
    foreach my $cmd (@process_list[1.. $#process_list]){
        $cmd =~ s/^s*//;
        $cmd =~ s/s*$//;
        my(@fields) = split /s+/, $cmd;

        $top_res{"$fields[-1]_$fields[-2]"}->{ "${ps_fields}_sum" } += $fields[0];
    }

    my @sorted_keys = sort { 
            $top_res{$b}->{"${ps_fields}_sum"} <=> $top_res{$a}->{"${ps_fields}_sum"} 
        } 
        keys %top_res;

    return (%top_res, @sorted_keys, "${ps_fields}_sum");
}

This function executes the ps command and will create a sum of the resource values per application and user. These values will be sorted in a descended way (highest will be first element in the list).

sub print_sorted {
    my($data, $sorted_keys, $sum_key, $limit) = @_;

    $limit ||= $#{$sorted_keys};

    my ($title) = ($sum_key =~ m/(.*?)_sum$/);

    print "====================[ TOP $limit OF $title ]======================n";
    foreach my $key ( @$sorted_keys[0..$limit] ) {
        my ($app, $user) = ( $key =~ /(.*?)_([^_]+)$/ );
    
        printf "%9.2ft%16st%16sn", $data->{$key}->{$sum_key}, $app, $user;
    }
    print "="x60, "nn";

}

This function will print out the data structures returned by get_proc_list().

We call these functions in one liner statements like:

print_sorted( get_proc_list('pcpu'), 20 );
print_sorted( get_proc_list('pmem'), 20 );
print_sorted( get_proc_list('rss'), 10 );

Sample output:

====================[ TOP 5 OF pcpu ]======================
     5.50	     firefox-bin	         dieterw
     2.90	          chrome	            phil
     2.60	            java	            dave
     2.50	 plugin-containe	             rob
     2.50	     firefox-bin	            dave
     2.40	     firefox-bin	             rob
============================================================

====================[ TOP 5 OF pmem ]======================
   375.10	            java	            dave
   346.00	            java	           fredv
    49.00	     firefox-bin	           fredv
    40.30	            java	         dieterw
    28.00	             exe	            phil
    19.20	 console-kit-dae	            root
============================================================

====================[ TOP 3 OF rss ]======================
123533296.00	            java	            dave
117568200.00	            java	           fredv
16021180.00	     firefox-bin	           fredv
14749020.00	            java	         dieterw
============================================================
Previous Post

Hacking the easy-fancybox WordPress plugin

Next Post

Blacklist emails with DCC through a Perl script

Related Posts