top is a well known command for monitoring resource consumption by processes in the system. It is commonly used in interactive mode but it is also useful within scripts. The next code shows how to use top command to monitor certain processes and log the output to a file:

#!/bin/bash
#
# Each row of the output of this script contains a date and the data 
# given by top command:
#
# date, PID, USER, PR, NI, VIRT, RES, SHR, S, %CPU, %MEM, TIME+, COMMAND    
#

# Add to this variable the processes you want to monitor
list_of_processes=("process1" "process2" "process3")

LOG_FILE=resources_monitor.log

while :
do
  for process in "${list_of_processes[@]}"
  do
    p_pid=$(ps aux | grep "$process\$" | awk '{print $2}')
    date=$(date +"%y-%m-%d %H:%M:%S.%N")
    res=$(top -b -p $p_pid -d 1 -n 1 | grep $p_pid)
    echo "$date $res" >> $LOG_FILE 2>&1
  done
  sleep 1
done

Now, I will explain the main lines of the script. The line:

p_pid=$(ps aux | grep "$process\$" | awk '{print $2}')

gets the pid of each process using ps and filtering the output using grep and the name of the process. Then, the second column of the output, which is the pid, is saved in the variable $p_pid.

The line:

res=$(top -b -p $p_pid -d 1 -n 1 | grep $p_pid)

uses top with argument -b for batch option, useful for sending output from top to other programs or to a file, -p for specify pid to show, -d is the delay between updates and -n is the number of iterations. Again, I use grep for filtering the output to just save the row with process info in variable $res.

Finally, the line:

echo "$date $res" >> $LOG_FILE 2>&1

appends the date and top information to a file specified in $LOG_FILE. The section 2>&1 redirects not just the stdout but also stderr to the file.

Advertisements