#!/usr/bin/env bash
# VICIfast Research, Report 01: The Two Bottlenecks Inside a Busy VICIdial Server
# Test harness. FOR A TEST SERVER, NOT A LIVE FLOOR. Read it before you run it.
# Sampler of the AMI router over one window. It resets Asterisk's taskprocessor counters
# ('core reset taskprocessor').
#
# env: LABEL, SECS. Measures the AMI router + Asterisk CPU + VICIdial call health over a window.
set +e
DB=$(awk -F'=> *' '/^VARDB_database/{print $2}' /etc/astguiclient.conf | tr -d ' \r'); M="mysql -N $DB"
W=/root/vf-engine-ab/ami; mkdir -p $W
TP=$(asterisk -rx 'core show taskprocessors' | awk '/stasis\/m:manager:core/{print $1; exit}')
asterisk -rx "core reset taskprocessor $TP" >/dev/null 2>&1
P=$(pidof asterisk | awk '{print $1}'); HZ=$(getconf CLK_TCK)
tk(){ awk '{print $14+$15}' /proc/$P/stat; }
pr(){ asterisk -rx 'core show taskprocessors' | awk -v n="$TP" '$1==n{print $2, $3, $4}'; }
t0=$(date '+%F %T'); s0=$(date +%s); k0=$(tk); read p0 q0 m0 < <(pr)
: > $W/q.$LABEL
end=$(( s0 + SECS ))
while [ $(date +%s) -lt $end ]; do
  read p q m < <(pr); ch=$(asterisk -rx 'core show channels count' | awk '/active call/{print $1}')
  bl=$($M -e "select count(*) from vicidial_manager where status='NEW' and entry_date < now() - interval 5 second")
  echo "$q $ch $bl" >> $W/q.$LABEL; sleep 2
done
t1=$(date '+%F %T'); s1=$(date +%s); k1=$(tk); read p1 q1 m1 < <(pr); S=$((s1-s0))
read calls drops < <($M -e "select count(*), sum(status='DROP') from vicidial_log where call_date between '$t0' and '$t1'")
read ans lost < <($M -e "select count(*), sum(v.status='NA') from vicidial_carrier_log c left join vicidial_log v on v.uniqueid=c.uniqueid where c.call_date between '$t0' and '$t1' and c.dialstatus='ANSWER'")
read matched < <($M -e "select count(*) from vicidial_carrier_log c join vicidial_log v on v.uniqueid=c.uniqueid where c.call_date between '$t0' and '$t1' and c.dialstatus='ANSWER'")
read xfer < <($M -e "select count(*) from vicidial_log where call_date between '$t0' and '$t1' and status='XFER'")
read closer cdrop < <($M -e "select count(*), sum(status in ('DROP','AFTHRS','NANQUE')) from vicidial_closer_log where call_date between '$t0' and '$t1'")
read recs < <($M -e "select count(*) from recording_log where start_time between '$t0' and '$t1'")
read stuck < <($M -e "select count(*) from vicidial_auto_calls where call_time < now() - interval 10 minute")
awk -v L=$LABEL -v S=$S -v ev=$((p1-p0)) -v mx=$m1 -v cpu=$(echo "scale=2; ($k1-$k0)/$HZ/$S" | bc) -v c=$calls -v d=${drops:-0} -v a=$ans -v lo=${lost:-0} -v mt=$matched -v x=$xfer -v cl=$closer -v cd=${cdrop:-0} -v r=$recs -v st=$stuck '
 {q+=$1; if($1>mq)mq=$1; ch+=$2; bl+=$3; if($3>mb)mb=$3; n++}
 END{printf "%s %ds | AMI router %.0f events/s, queue avg %.1f max %d (lifetime-reset max %d) | asterisk %.2f cores | calls at once avg %.0f\n   calls %.2f/s drops %d | answered %d (joined %d) lost-as-NA %d (%.2f%%) | XFER %d | closer_log %d (dropped %d) | recordings %d | AMI cmd backlog >5s avg %.1f max %d | auto_calls >10min %d\n",
  L,S,ev/S,q/n,mq,mx,cpu,ch/n,c/S,d,a,mt,lo,(a?100*lo/a:0),x,cl,cd,r,bl/n,mb,st}' $W/q.$LABEL
