#!/usr/bin/perl -w use strict; ## Scott Wiersdorf ## Created: Mon Aug 15 10:40:14 MDT 2005 ## $Id: psmon,v 1.1 2005/08/15 18:25:30 scott Exp $ ## simple process monitor use Getopt::Std; our ($opt_h, $opt_u, $opt_s, $opt_S, $opt_t); getopts('hu:s:S:t:'); ## make sure this directory exists in /tmp and has correct permissions our $Table = ($opt_t ? $opt_t : "$ENV{HOME}/.psmontab"); our $Cmd = qq(/bin/ps -axo pid,user,command); usage() if $opt_h; ## ## read previous table ## my %pstab = (); if( -f $Table ) { open TAB, $Table or die "Could not read psmon table: $!\n"; while( ) { chomp; my($pid, $puser, $comm) = split(' ', $_, 3); $pstab{$pid} = "$puser $comm"; } close TAB; } ## ## read current process table and look for duplicates ## open TAB, ">$Table.$$" or die "Could not write temporary table: $!\n"; open PS, "$Cmd|" or die "Could not exec ps: $!\n"; while( ) { print TAB; chomp; my($pid, $puser, $comm) = split(' ', $_, 3); if( $opt_u ) { next unless $opt_u eq $puser } if( $opt_s ) { next unless $comm =~ qr($opt_s) } if( $opt_S ) { next unless $comm !~ qr($opt_S) } print "Process found: $pid [$puser] $comm\n" if $pstab{$pid}; } close PS; close TAB; ## ## dump new ps table ## rename "$Table.$$", $Table; exit; sub usage { die <<'_USAGE_'; usage: psmon [-u user] [-s 'include pattern'] [-S 'exclude pattern'] [-t /path/to/table] The first time psmon is run, it will write the process table to disk. Subsequent runs will compare the current process table with the cached copy. Any duplicates found will be printed to stdout. Options include: -u user look for processes owned by this user -s 'inc pat' only examine processes that match this pattern (Perl regex) -S 'exc pat' only examine processes that do not match this pattern (Perl regex) -t /path/table alternative path to the process table cache (default $HOME/.psmontab) This may be run from cron: MAILTO=admin */5 * * * * psmon -u joe -s 'mybig\.cgi' Every 5 minutes, psmon will look for duplicate processes and write them out: Process found: 1442 [joe] perl /cgi-bin/mybig.cgi Some pattern examples: ## look at all processes with 'sh' in them, except 'ssh' and 'bash' psmon -u joe -s 'sh' -S '(?:ssh|bash)' ## apache (httpd and httpsd) psmon -u www -s 'https?d' _USAGE_ }