#!/bin/ksh -p # ################################################################## # FUNCTIONS # # Date:13OCT2004 # Author: Stefan Parvu # # TOTAL FUNCTIONS: 5 # usage - describes the usage for this tool # version - revision control # strval - string validator, returns what type of input has received # patrolplugin - plugin to format data vs. BMC/Best1 Patrol # csvplugin - plugin to format data vs Comma Separated Values # ################################################################## function usage { print "" print "Usage:\t${0##*/} [options] pid1 [pid2...pidn]" print "Options:" print "\t-m minutes\tthe recording time in minutes" print "\t-h hours\tthe recording time in hours" print "\t-d days\t\the recording time in days" print "\t-i interval\tthe time interval between samples" print "\t-p plugin\tenable collection mode" print "\t-c CID\t\tcollection id" print "\t-v|V\t\tversion information" print "" print "If no interval is specified 10 seconds step is applied" print "" } function version { print "" print "STLBox - version 1.7.0" print "Module: pcollector" print "Status: Production" print "" } function strval { if (($# != 1)) then print "[pcollector:error] Internal error: wrong number of parameters" return fi CHR=$1 case "${CHR}" in +([1-9])*([0-9])) print 'POS_INT' ;; +([-0-9])) print 'NEG_INT' ;; +([a-z])) print 'LOW_CASE' ;; +([A-Z])) print 'UP_CASE' ;; +([a-z]|[A-Z])) print 'MIX_CASE' ;; *) print 'NOT DEFINED' ;; esac } # ############################################# # BMC/Best1 Patrol plugin # Description: # $1 - "pid1 pid2 pid3" - A list of pids [1..n] # $2 - secs 60-n - A sleep value >= 60 secs # ############################################# function patrolplugin { integer i=0 p=0 count=1 fds=0 nlwp=0 vsz=0 rss=0 ii=0 cid_plugin= comm= s= hostname=$(uname -n) i=$2 cid_plugin="${3}" ii=$((i/60)) set -- $1 while : do for p in $@ do if [[ ! -r /proc/${p} ]] then logger -p daemon.notice "pcollector($#): ALERT lost target ${p} from pidlist: $@ - aborting" exit 2 fi done d1=$(date +"%y/%m/%d,%H%M") for p in $@ do ps -o nlwp= -o vsz= -o rss= -o comm= -p ${p} | { read nlwp vsz rss comm ls /proc/${p}/fd 2>/dev/null | wc -l | read fds print -- \ ";$d1,$ii ;$hostname,${cid_plugin}.${comm##*/}.${count},,,$fds,$nlwp,$vsz,$rss $hostname" } (( count=count+1 )) done s=$(date +"%S") count=1 sleep $((i-s%i)) done } # ############################################# # CSV Patrol plugin # Description: # $1 - "pid1 pid2 pid3" - A list of pids [1..n] # $2 - secs 60-n - A sleep value >= 60 secs # ############################################# function csvplugin { integer i=0 p=0 count=1 fds=0 nlwp=0 vsz=0 rss=0 ii=0 cid_plugin= comm= s= d1= d2= d3= hostname=$(uname -n) i=$2 cid_plugin="${3}" ii=$((i/60)) set -- $1 while : do for p in $@ do if [[ ! -r /proc/${p} ]] then logger -p daemon.notice "pcollector($#): ALERT lost target ${p} from pidlist: $@ - aborting" exit 2 fi done d1=$(date +"%y/%m/%d") d2=$(date +"%H%M") d3=$("${AWKPRG}" 'BEGIN { print srand }') for p in $@ do ps -o nlwp= -o vsz= -o rss= -o comm= -p ${p} | { read nlwp vsz rss comm ls /proc/${p}/fd 2>/dev/null | wc -l | read fds print -- \ "\"$d3\",\"$ii\",\"$hostname\",\"${cid_plugin}.${comm##*/}.${count}\",\"$fds\",\"$nlwp\",\"$vsz\",\"$rss\"" } (( count=count+1 )) done s=$(date +"%S") count=1 sleep $((i-s%i)) done } # ############# # # MAIN FUNCTION # # ############# integer MINS=0 HRS=0 DAYS=0 pid=0 interval=0 total_time=0 plugin=0 int_sem=0 fds=0 plugin_cid_sem=0 s=0 group_pid= plugin_name= plugin_cid= dates= BOLD=$(tput bold) BOLDOFF=$(tput sgr0) case "$(uname)" in SunOS) AWKPRG='/usr/bin/nawk' ;; *) print "[pcollector:error] Operating system not supported at this time!" exit 1 ;; \?) print "[pcollector:error] Operating system not supported at this time!" exit 1 ;; esac while getopts ":m:h:d:i:p:c:vV" arg do case "${arg}" in m) [[ $(strval $OPTARG) != 'POS_INT' ]] && usage && exit 1 (( MINS=$OPTARG*60 )) ;; h) [[ $(strval $OPTARG) != 'POS_INT' ]] && usage && exit 1 (( HRS=$OPTARG*3600 )) ;; d) [[ $(strval $OPTARG) != 'POS_INT' ]] && usage && exit 1 (( DAYS=$OPTARG*86400 )) ;; i) int_sem=1 interval=$OPTARG [[ $(strval $OPTARG) != 'POS_INT' ]] && usage && exit 1 ;; p) plugin=1 plugin_name=$OPTARG ;; c) plugin_cid_sem=1 plugin_cid=$OPTARG ;; v|V) version exit 0 ;; \?) usage exit 1 ;; esac done shift $(($OPTIND - 1)) (( total_time=MINS+HRS+DAYS )) if (( $# < 1 )) then usage exit 1 fi if (( plugin == 1 )) then case "${plugin_name}" in patrol) for p in $@ do if [[ ! -r /proc/${p} ]] then print "[pcollector:error] Cannot access process id: ${p}" print "[pcollector:info] Process not found or permission denied" exit 2 fi done if (( interval > 0 && interval < 60 )) then print "[pcollector:error] Invalid sleep interval: ${interval} seconds" print "[pcollector:info] The sleep interval should be at least 60 seconds !" exit 2 else if (( interval == 0 )) then interval=60 fi fi if (( plugin_cid_sem == 1 )) then patrolplugin "$*" ${interval} "${plugin_cid}" else patrolplugin "$*" ${interval} "" fi exit $? ;; smc|tq) print "[pcollector:info] SMC and TeamQuest plugins are not implemented at this time" exit 0 ;; csv) for p in $@ do if [[ ! -r /proc/${p} ]] then print "[pcollector:error] Cannot access process id: ${p}" print "[pcollector:info] Process not found or permission denied" exit 2 fi done if (( interval > 0 && interval < 60 )) then print "[pcollector:error] Invalid sleep interval: ${interval} seconds" print "[pcollector:info] The sleep interval should be at least 60 seconds !" exit 2 else if (( interval == 0 )) then interval=60 fi fi if (( plugin_cid_sem == 1 )) then csvplugin "$*" ${interval} "${plugin_cid}" else csvplugin "$*" ${interval} "" fi exit $? ;; *) print "[pcollector:error] Not supported plugin: ${plugin_name}" print "[pcollector:info] Supported plugins: csv, patrol, tq, smc" exit 255 ;; esac fi for p in $@ do [[ $(strval $p) != 'POS_INT' ]] && usage && exit 1 done integer kk=0 for p in $@ do if [[ ! -r /proc/${p} ]] then print "[pcollector:error] Cannot access process id: ${p}" print "[pcollector:info] Process not found or permission denied" exit 2 fi pidl[kk]=${p} (( kk = kk +1 )) done if (( ${#pidl[*]} == 0 )) then print "" print "[pcollector:error] Can't find any valid processes pid to process!" print "[pcollector:info] Please check all input processes id" print "" exit 2 fi # print "[pconsole:debug] Valid process pid: ${pidl[*]}" if (( total_time == 0 )) then if (( int_sem == 1 )) then print "\n$(uname -rsnvp)\t$(date +"%Y/%m/%d")\n" printf "%-10s %-20s %7s %7s %11s %11s\n" "time" "process name" "fds" "nlwp" "vsz" "rss" integer cnt=0 while : do integer l=0 for pp in ${pidl[*]} do if [[ ! -r /proc/${pp} ]] then print "[pcollector:error] Cannot read process-id: ${pp}" print "[pcollector:info] Check if the process is running !" exit 255 fi done if (( cnt == 10 )) then printf "\n%-10s %-20s %7s %7s %11s %11s\n" "time" "process name" "fds" "nlwp" "vsz" "rss" cnt=0 fi dates=$(date +"%T") for pp in ${pidl[*]} do ps -o nlwp= -o vsz= -o rss= -o comm= -p ${pp} | { read nlwp vsz rss comm ls /proc/${pp}/fd 2>/dev/null | wc -l | read fds if (( l == 0 )) then printf "%-10s %-20s %7s %7s %11s %11s\n" "$dates" "${comm##*/}" "$fds" "$nlwp" "$vsz" "$rss" else printf "%-10s %-20s %7s %7s %11s %11s\n" "" "${comm##*/}" "$fds" "$nlwp" "$vsz" "$rss" fi } (( l = l + 1 )) done s=$(date +"%S") (( cnt = cnt + 1 )) sleep $((interval-s%interval)) done else print "\n$(uname -rsnvp)\t$(date +"%Y/%m/%d")\n" printf "%-10s %-20s %7s %7s %11s %11s\n" "time" "process name" "fds" "nlwp" "vsz" "rss" integer l=0 dates=$(date +"%T") for pp in ${pidl[*]} do ps -o nlwp= -o vsz= -o rss= -o comm= -p ${pp} | { read nlwp vsz rss comm ls /proc/${pp}/fd 2>/dev/null | wc -l | read fds if (( l == 0 )) then printf "%-10s %-20s %7s %7s %11s %11s\n" "$dates" "${comm##*/}" "$fds" "$nlwp" "$vsz" "$rss" else printf "%-10s %-20s %7s %7s %11s %11s\n" "" "${comm##*/}" "$fds" "$nlwp" "$vsz" "$rss" fi } (( l = l + 1 )) done fi else # well loop in here according with the total_time defined by user if (( interval == 0 )) then interval=10 fi print "\n$(uname -rsnvp)\t$(date +"%Y/%m/%d")\n" printf "%-10s %-20s %7s %7s %11s %11s\n" "time" "process name" "fds" "nlwp" "vsz" "rss" integer CURRENT_TIME=0 (( TIME_TO_FINISH= $("${AWKPRG}" 'BEGIN { print srand }') + total_time )) integer cnt=0 while (( CURRENT_TIME <= TIME_TO_FINISH )) do for pp in ${pidl[*]} do if [[ ! -r /proc/${pp} ]] then print "[pcollector:error] Cannot read process-id: ${pp}" print "[pcollector:info] Check if the process is running !" exit 255 fi done if (( cnt == 10 )) then printf "\n%-10s %-20s %7s %7s %11s %11s\n" "time" "process name" "fds" "nlwp" "vsz" "rss" cnt=0 fi integer l=0 dates=$(date +"%T") for pp in ${pidl[*]} do ps -o nlwp= -o vsz= -o rss= -o comm= -p ${pp} | { read nlwp vsz rss comm ls /proc/${pp}/fd 2>/dev/null | wc -l | read fds if (( l == 0 )) then printf "%-10s %-20s %7s %7s %11s %11s\n" "$dates" "${comm##*/}" "$fds" "$nlwp" "$vsz" "$rss" else printf "%-10s %-20s %7s %7s %11s %11s\n" "" "${comm##*/}" "$fds" "$nlwp" "$vsz" "$rss" fi } (( l=l+1 )) done s=$(date +"%S") CURRENT_TIME=$("${AWKPRG}" 'BEGIN { print srand }') (( CURRENT_TIME=CURRENT_TIME+interval )) (( cnt=cnt+1 )) sleep $((interval-s%interval)) done fi