Monitoring process CPU and memory usage
This article contains examples of using prstat to monitor CPU and memory utilization by individual processes and groups of processes.
Example 1: Show CPU and memory usage by all processes called “*ora_smon_imanax*”
The following prstat command will take two data samples at a 3-second interval. If there are more than one process that matches the “ora_smon_imanax” string, the “-t” option will total the output.
prstat -p `ps -ef | fgrep "ora_smon_imanax" | awk '{print $2}' | tr 'n' ,` -c -t 3 2
The output looks something like this on Solaris 8:
NPROC USERNAME SIZE RSS MEMORY TIME CPU
1 oracle 458M 437M 1.4% 0:00.00 0.0%
Total: 1 processes, 1 lwps, load averages: 2.52, 2.14, 1.87
NPROC USERNAME SIZE RSS MEMORY TIME CPU
1 oracle 458M 437M 1.4% 0:00.00 0.0%
Total: 1 processes, 1 lwps, load averages: 2.52, 2.15, 1.87
Example 2: Write a script to keep a log of CPU and memory utilization by all processes called “*quest*”. Write the log in character-separated format that can be imported into a spreadsheet to produce a timeline chart.
#!/bin/ksh
# igor@krazyworks.com
# December 14. 2005
# This script collects CPU and Memory utilization data
# for the Quest-related processes.
# SUPPORTED SYSTEMS:
#---------------------------------------------------------------
# OS Name OS Version Tested
#---------------------------------------------------------------
# SunOS 5.8 Y
#---------------------------------------------------------------
#---------------------------------------------------------------
# FUNCTIONS
#---------------------------------------------------------------
log() {
LOG="/var/log/questmon.log"
TMP="/tmp/questmon_log.tmp"
LINELIM=10000 ; LINEBUF=50 ; (( LINEMAX = LINELIM + LINEBUF ))
if [ ! -r "$LOG" ]
then
touch "$LOG"
fi
if [ -f "$LOG" ] && [ `wc -l "$LOG" | awk '{print $1}'` -gt $LINEMAX ]
then
cat "$LOG" | tail -$LINELIM > "$TMP"
mv "$TMP" "$LOG"
fi
}
config() {
KEY="quest"
PIDLIST=$(ps -ef | fgrep "$KEY" | fgrep -v fgrep | awk '{print $2}')
PIDLIST=$(echo "$PIDLIST" | tr 'n' ,)
LINE=$(prstat -p "$PIDLIST" -c -t 1 1 | egrep % | tail -1)
SIZE=0 ; RSS=0 ; MEMORY=0 ; TIME=0 ; CPU=0
}
parse() {
SIZE=$(echo "$LINE" | awk '{print $3}')
if [ `echo "$SIZE" | grep -c K` -eq 1 ]
then
SIZE=$(echo "$SIZE" | sed 's/K//g')
SIZE=$(echo "$SIZE*1" | bc -l)
elif [ `echo "$SIZE" | grep -c M` -eq 1 ]
then
SIZE=$(echo "$SIZE" | sed 's/M//g')
SIZE=$(echo "$SIZE*1024" | bc -l)
elif [ `echo "$SIZE" | grep -c G` -eq 1 ]
then
SIZE=$(echo "$SIZE" | sed 's/G//g')
SIZE=$(echo "$SIZE*1024*1024" | bc -l)
fi
RSS=$(echo "$LINE" | awk '{print $4}')
if [ `echo "$RSS" | grep -c K` -eq 1 ]
then
RSS=$(echo "$RSS" | sed 's/K//g')
RSS=$(echo "$RSS*1" | bc -l)
elif [ `echo "$RSS" | grep -c M` -eq 1 ]
then
RSS=$(echo "$RSS" | sed 's/M//g')
RSS=$(echo "$RSS*1024" | bc -l)
elif [ `echo "$RSS" | grep -c G` -eq 1 ]
then
RSS=$(echo "$RSS" | sed 's/G//g')
RSS=$(echo "$RSS*1024*1024" | bc -l)
fi
MEMORY=$(echo "$LINE" | awk '{print $5}' | sed 's/%//g')
TIME=$(echo "$LINE" | awk '{print $6}')
CPU=$(echo "$LINE" | awk '{print $7}' | sed 's/%//g')
}
write() {
echo "`date +'%Y-%m-%d %H:%M:%S'`@${SIZE}@${RSS}@${MEMORY}@${TIME}@${CPU}" >> "$LOG"
}
#---------------------------------------------------------------
# RUNTIME
#---------------------------------------------------------------
log
config
parse
write
If you run this script from cron every few minutes, the output would look something like this:
2005-12-15 10:20:01@3526656@3151872@6.5@0:00.00@0.0 2005-12-15 10:25:01@3526656@3151872@6.5@0:00.00@0.0 2005-12-15 10:30:00@3526656@3151872@6.5@0:00.00@0.0 2005-12-15 10:35:00@3526656@3151872@6.5@0:00.00@0.0 2005-12-15 10:40:01@3526656@3151872@6.5@0:00.00@0.0 2005-12-15 10:45:00@3526656@3151872@6.5@0:00.01@0.0 2005-12-15 10:50:01@3526656@3151872@6.5@0:00.01@0.0 2005-12-15 10:55:01@3526656@3151872@6.5@0:00.01@0.0 2005-12-15 11:00:00@3526656@3151872@6.5@0:00.01@0.0 2005-12-15 11:05:01@3526656@3151872@6.5@0:00.01@0.0 2005-12-15 11:10:01@3526656@3151872@6.5@0:00.01@0.0 2005-12-15 11:15:01@3526656@3151872@6.5@0:00.01@0.0 2005-12-15 11:20:01@3526656@3151872@6.5@0:00.01@0.0

