#!/bin/bash
# -*- mode: shell-script; indent-tabs-mode: t; sh-basic-offset: 4; sh-indentation: 4; tab-width: 8 -*-

PROG="$(basename ${0})"

tool_output_dir="${1}"
if [[ ! -d "${tool_output_dir}" ]]; then
    printf -- "%s: invalid tool output directory, '%s'\n" "${PROG}" "${tool_output_dir}" >&2
    exit 1
fi

interval="${2}"
if [[ -z "${interval}" ]]; then
    printf -- "%s: missing required 'interval' argument\n" "${PROG}" >&2
    exit 1
fi

pid_to_jmap="${3}"
if [[ -z "${pid_to_jmap}" ]]; then
    printf -- "%s: missing PID to jmap\n" "${PROG}" >&2
    exit 1
fi

command -v jmap > /dev/null
if [[ ${?} -ne 0 ]]; then
    printf -- "%s: missing 'jmap' command\n" "${PROG}" >&2
    exit 1
fi

if [[ "${pid_to_jmap}" == "0" ]]; then
    pid_to_jmap=""
fi
pattern="${4}"
if [[ -z "${pattern}" ]]; then
    pattern="java"
fi

rc=0
while [[ ${rc} -eq 0 ]]; do
    # get java pids running on host.
    jvm_pids="$(pgrep "${pattern}") ${pid_to_jmap}"

    for jvm_pid in ${jvm_pids}; do
	# check if containerized.
	cnt=$(grep -cF 'user.slice' /proc/${jvm_pid}/cgroup 2> /dev/null)
	if [[ ${?} -eq 0 && ${cnt} -eq 0 ]]; then
	    jpid=$(grep hsperfdata /proc/${jvm_pid}/task/${jvm_pid}/maps | awk -F "hsperfdata" '{print $2}' | sed "s/[^0-9]//g")
	    heap_used=$(nsenter --target ${jvm_pid} --mount --uts --ipc --net --pid jmap -histo ${jpid} | grep Total | awk '{print $3/1024/1024}')
	else
	    heap_used=$(jmap -histo ${jvm_pid} | grep Total | awk '{print $3/1024/1024}')
	fi
	# map pid to process name.
	ls -A /proc/${jvm_pid}/cmdline > /dev/null 2>&1
	if [[ ${?} -eq 0 ]]; then
	    jvm_pid=$(echo "${jvm_pid}-$(cat /proc/${jvm_pid}/cmdline)")
	fi
	echo "$(date "+%s"),${jvm_pid},${heap_used}"
    done

    sleep ${interval}
    rc=${?}
done
