Created
April 17, 2010 22:39
-
-
Save mberends/369869 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl -w | |
# process-monitor.pl | |
# Only tested on Linux - uses the /proc virtual filesystem | |
use Getopt::Long; | |
use Time::HiRes; | |
my ( | |
$sampling_interval, # interval for sampling process info (0.1sec) | |
$display_interval # interval for displaying results (off) | |
) = ( 0.1, 0.0 ); | |
Getopt::Long::Configure(require_order); | |
GetOptions( | |
"sampling=f" => \$sampling_interval, | |
"display=f" => \$display_interval | |
); | |
@ARGV == 0 and die <<USAGE; | |
Usage: $0 [options] <command line> | |
options: | |
--sampling=n.n monitor every n.n seconds | |
--display=n.n display every n.n seconds | |
USAGE | |
# become two processes, a monitor (parent) and a command (child) | |
my $process_id = fork(); | |
$| = 1; # flush after every print | |
# divide the flow control of parent and child | |
if ( $process_id ) { | |
# parent here | |
my ( $size_max, $vsize_max, $child_running, $time_begin ) = | |
( 0, 0, 1, Time::HiRes::time ); | |
my $time_display = $time_begin + $display_interval; | |
# loop until the child process ends | |
while ( $child_running ) { | |
# sample data every 0.1 seconds | |
Time::HiRes::sleep $sampling_interval; | |
# not sure whether the desired data should come from | |
# /proc/[pid]/statm or /proc/[pid]/stat, so read both. | |
# statm measures memory usage in pages | |
open my $statm_file, "<", "/proc/$process_id/statm"; | |
my $statm_data = <$statm_file>; | |
close $statm_file; | |
my ( $size, $resident, $share, $text, $lib, $data, $dt ) = | |
split " ", $statm_data; | |
# stat returns lots of process info | |
open my $stat_file, "<", "/proc/$process_id/stat"; | |
my $stat_data = <$stat_file>; | |
close $stat_file; | |
my @stat_data = split " ", $stat_data; | |
my ( $pid, $comm, $state, $ppid, $pgrp, $session,$tty_nr, | |
$tpgid, $flags, $minflt, $cminflt, $majflt, $cmajflt, | |
$utime, $stime, $cutime, $cstime, $priority, $nice, | |
$num_threads, $itrealvalue, $starttime, $vsize, $rss, | |
$rsslim, $startcode, $endcode, $startstack, $kstkesp, | |
$kstkeip, $signal, $blocked, $sigignore, $sigcatch, $wchan, | |
$nswap, $cnswap, $exit_signal, $processor, $rt_priority, | |
$policy, $delayacct_blkio_ticks, $guest_time, $cguest_time | |
) = @stat_data; | |
$child_running = ($state ne 'Z'); | |
$size_max = $size if ( $size_max < $size ); | |
$vsize_max = $vsize if ( $vsize_max < $vsize ); | |
if ( $display_interval > 0 and Time::HiRes::time > $time_display ) { | |
my $time_done = int(10*(Time::HiRes::time - $time_begin))/10; | |
print "Time_done=$time_done(sec) size_max=$size_max(blocks) vsize_max=$vsize_max(bytes)\n"; | |
$time_display += $display_interval; | |
} | |
} | |
my $time_end = Time::HiRes::time; | |
my $time_run = int(10*($time_end - $time_begin))/10; | |
print "Time_run=$time_run(sec) size_max=$size_max(blocks) vsize_max=$vsize_max(bytes)\n"; | |
} | |
else { | |
# child here | |
my $command = shift @ARGV; | |
exec $command, @ARGV or die "$0 cannot exec $command @ARGV: $!\n"; | |
} | |
=pod | |
=head1 REFERENCES | |
Read L<perlipc> and the stat and statm sections in C<man proc>. | |
=head1 LICENSE | |
I wrote this program for you to copy and use, without warranty, at your | |
risk. Give appropriate credit if you do. Best wishes, Martin Berends. | |
=cut |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment