BASH: консольный график использования памяти Java-машиной

Автор: | 10/07/2014

terminalЗадача – сделать консольную утилиту, которая выводила бы информацию аналогично visualvm – Used heap + писать в лог.

Для получения данных от Java-машины – используем jmap.

Предполагается, что мониторить мы будем Tomcat с заданной переменной CATALINA_PID.

Сам скрипт:

#!/usr/bin/env bash

# задаём цвета - если больше 75% то "график" грасный
green="E[32;40m"
red="E[31;40m"

# расположение лога
log="$OUTPUT_DIR/memmon.log"

# главная функция-рисовалка
print () {

printf "Total: $2 MBt"

# пока i меньше, чем переденное значение $short - рисовать |
for((i=1;i<=$1;i++)); do
  printf "$3%s" "|"
done
printf "n"
# сбрасываем значение цвета консоли перед следующей итерацией
tput sgr0
}

# временный файл для результатов jmap
if [ ! -e "/tmp/jmap.log" ]; then
  touch "/tmp/jmap.log"
fi

# нам наличие PID Tomcat'a необходимо, можно просто задать переменную pid напрямую
if ! pid=$(cat $CATALINA_HOME/conf/catalina.pid); then
  echo "ERROR! Can't find Tomcat's PID-file. Exit."
  exit 1
fi

if [ ! -e "$log" ]; then
  touch "$log"
fi

# при каждой итерации цикла while - записываем данные в лог
jmapsave () {
  jmap -heap "$1" &> /tmp/jmap.log
}

# получаем различные значения из лога
jmapgetnum () {
jmapsave "$pid"
cat /tmp/jmap.log | grep "used =*" | awk '{print $4}' | cut -d"." -f 1 | sed 's/(//g' | tail -n $1 | head -n 1
}

# вычислияем MaxHeapSize
jmapgetmax () {
max=$(cat /tmp/jmap.log | grep -E "$1" | awk '{print $4}' | cut -d"." -f 1 | sed 's/(//g')
}

echo -e "Memory monitoring started at $(date +%Y-%m-%d %H:%M)n" | tee -a "$log"

# когда нажмут Ctrl+C - записываем время прекращения мониторинга
trap 'echo -e "nMemory monitoring finished at $(date +%Y-%m-%d %H:%M)n" | tee -a "$log"; exit 2' 2

# начинаем выполнение
while true; do

jmapgetmax "MaxHeapSize"

# задаём занчения переменных из функции jmapgetnum
pspermgeng=$(jmapgetnum 1)
psoldgen=$(jmapgetnum 2)
youngtospace=$(jmapgetnum 3)
yongfromspace=$(jmapgetnum 4)
yongedenspace=$(jmapgetnum 5)

# если какая-то из переменных пустая - будут ошибки, задаём значение 0
: ${pspermgeng:=0}
: ${psoldgen:=0}
: ${youngtospace:=0}
: ${yongfromspace:=0}
: ${yongedenspace:=0}

# суммируем значение переменных из переменных
heapmax=$(( psoldgen + youngtospace + yongfromspace + yongedenspace ))
full=$(( ( pspermgeng + psoldgen + youngtospace + yongfromspace + yongedenspace) ))
# если памяти много и строка графика в консоли слишком длинная - увеличиваем тут значение, например / 30
short=$(( $full / 10 ))
# вычисляем процент занятой от MaxHeapSize памяти
percent=$(echo "$heapmax*100/$max"| bc)
yong=$(( yongedenspace + yongfromspace + youngtospace ))

# more defaults
: ${heapmax:=0}
: ${full:=0}
: ${short:=0}
: ${percent:=0}
: ${yong:=0}

# save to log-file
echo "Young Generation: "$yong";" >> "$log"
echo "Old Generation: "$psoldgen";" >> "$log"
echo -e "Perm Generation: "$pspermgeng".n" >> "$log"

# раскрашиваем вывод - измените, при необходимости - если более 70% занято - рисовать красный график
if [ "$percent" -lt 70 ]; then
  color=$green
  else
  color=$red
fi

# и запускаем функцию print в цикле, пока не будет Ctrl+C
print "$short" "$full" "$color"

sleep 10

done

Выполнение:

$ ./memgraph
Memory monitoring started at 2014-07-08 13:45

Total: 902 MB ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 909 MB ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 917 MB |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 923 MB ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 930 MB |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 939 MB |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 945 MB ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 953 MB |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 960 MB ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 967 MB ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 974 MB |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 981 MB ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 990 MB |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 996 MB |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 1003 MB ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 1011 MB |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 1018 MB |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 1026 MB ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 1033 MB |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 1040 MB ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 1048 MB ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 1055 MB |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 1063 MB ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Total: 1070 MB |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
^C
Memory monitoring finished at 2014-07-08 13:51

Лог-файл:

$ tail -n 30 ../logs/memmon.log
Memory monitoring started at 2014-07-08 13:51

Young Generation: 5;
Old Generation: 617;
Perm Generation: 120.

Young Generation: 12;
Old Generation: 617;
Perm Generation: 120.

Young Generation: 19;
Old Generation: 617;
Perm Generation: 120.

Young Generation: 27;
Old Generation: 617;
Perm Generation: 120.

Young Generation: 34;
Old Generation: 617;
Perm Generation: 120.

Memory monitoring finished at 2014-07-08 13:52