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