Custom Monitor VoIP

Prev Next

Introduction

Today, most organizations use VoIP for basic communication and rely on the quality of this service. The quality of VoIP has improved over the last few years with ISPs offering more reliable connectivity. This has helped increase the subscription of VoIP service, but issues affecting VoIP quality persist. It is essential to monitor your VoIP service to identify issues and resolve them.

In the VoIP world, we often use Mean Opinion Score or MOS as a quality metric. MOS score is calculated by considering network latency, packet loss, and jitter. The score is a value between 1 and 5 with good quality in the range of 3.2 and above.

With Custom Monitor you can proactively monitor for issues specific to VoIP service. You can build a script using the ping utility to capture important information like latency, jitter, and MOS to determine the quality of your VoIP service.

Learn more about Custom Monitor by reading this article

Prerequisites

The VoIP monitor uses the existing ping utility to ping your VoIP server and gather data. The ping utility defaults to ICMP-based pings. So, if you want to test VoIP based on TCP-Ping, you may need to install a third-party utility.

We tested several utilities and found hpingto have the best experience.

Installation & Configuration

  1. Install hping
    $ yum -y install hping

  2. Test the hping installation
    $ yum whatprovides hping3

Note: hping3 is released under the GPL License Version 2

Implementation

Write the Custom Script**

  1. Navigate to /opt/3genlabs/hawk/syntheticnode/service/shellmonitor/sandbox to create a shell script:
    $ vi voip_tcpping.sh

  2. Paste the code below and save it:

#!/bin/sh
ip_regex='^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$'
host=${CP_UNSAFE_VAR_host}
count=${CP_UNSAFE_VAR_count}
if [[ $host =~ $ip_regex ]]
then
echo "Host:" $host
for i in $(bash -c "echo {1..${count}}");
do
    start_time=$(date +%s%3N)
    ping_output=$(hping $host -c 1 2>&1)
    stop_time=$(date +%s%3N)

#ping_start_time=$(echo {$ping_output} | grep -P '\[(\d+.\d+)\]' -o | grep -P '(\d+.\d+)' -o)
    #start_time=$(date +%s%3N -d @$ping_start_time)

time_diff=$(echo {"(($stop_time - $start_time)/1000)"} | bc -l)
    #echo "Time Diff:" $time_diff

#echo $ping_output
    temp_packet_sent=$(echo {$ping_output} | grep -P '(\d) packets transmitted' -o | grep -P '(\d)' -o)
    temp_packet_replies=$(echo {$ping_output} | grep -P '(\d) packets received' -o | grep -P '(\d)' -o)
    temp_packet_loss=$(echo {$ping_output} | grep -P '(\d+)% packet loss' -o | grep -P '(\d+)' -o)

packet_sent[$i]=$temp_packet_sent
    packet_replies[$i]=$temp_packet_replies
    packet_loss[$i]=$temp_packet_loss

rtt_array[$i]=$(echo {$ping_output} | grep -P 'rtt=(\d+.\d+) ms' -o | grep -P '(\d+.\d+)' -o)
    latency[$i]=$time_diff
    #For latency we need the difference of start time and end time placed before and after the ping statement
done

#Calculate Packet Setnt & Packet Loos
total_packet_sent=0
total_packet_replies=0
for element in "${packet_sent[@]}"
do
    total_packet_sent=$(( $total_packet_sent+$element ))
done
echo "Total Packet Sent:" $total_packet_sent

for element in "${packet_replies[@]}"
do
    total_packet_replies=$(( $total_packet_replies+$element ))
done
echo "Total Packet Replies:" $total_packet_replies

total_packet_loss=$(echo {"(($total_packet_replies/$total_packet_sent)*100)-100"} | bc -l)
printf "Packet Loss: %.2f\n" "$(echo $total_packet_loss)"

#calculate latency
total_latency=0
for element in "${latency[@]}"
do
    #echo $element
    #((avg_latency+=echo {"$element"} | bc))
    total_latency=$(echo {"$total_latency+$element"} | bc)
done
avg_latency=$(echo {"$total_latency/$count"} | bc -l)
printf "Avg. Latency: %.3f\n" "$(echo $avg_latency)"

echo "RTT Summary"

#Calculate Jitter
previous_index=1
for index in "${!rtt_array[@]}"
do
    echo "$index ${rtt_array[index]}"
    #counter=$(echo "$index ${array[index]}")
    if [ $index -ne 1 ]; then

   #echo ${rtt_array[index]}

   #echo "Index:" ${rtt_array[index]}

   #echo "Previous Index" ${rtt_array[previous_index]}

   tmp_jitter=$(echo {"${rtt_array[index]}-${rtt_array[previous_index]}"} | bc )

   negative_check=$(echo {"$tmp_jitter<0"} | bc)

   #echo "Temp Jitter Value:"$negative_check

   if [ $negative_check -eq 1 ]; then

   jitter_delta[previous_index]=$(echo {"${tmp_jitter}*-1"} | bc -l)

   else

   jitter_delta[previous_index]=$tmp_jitter

   fi

   ((previous_index++))
    fi
done

total_jitter=0.00
for element in "${jitter_delta[@]}"
do
    #echo $element
    #((avg_jitter+=echo {"$element"} | bc))
    total_jitter=$(echo {"$total_jitter+$element"} | bc)
done

avg_jitter=$(echo {"$total_jitter/4"} | bc -l)
printf "Avg. Jitter: %.3f\n" "$(echo $avg_jitter)"

#calculate MOS
#Take the average latency, add jitter, but double the impact to latency then add 10 for protocol latencies
effective_latency=$(echo {"$avg_latency+$avg_jitter*2+10"} | bc -l)

#Implement a basic curve - deduct 4 for the R value at 160ms of latency (round trip).  Anything over that gets a much more agressive deduction
effective_latency_check=$(echo {"$effective_latency<160"} | bc)
if [ $effective_latency_check -eq 1 ]; then
    r_value=$(echo {"93.2-($effective_latency/40)"} | bc -l)
else
    r_value=$(echo {"93.2-($effective_latency-120)/10"} | bc -l)
fi

#Now, let's deduct 2.5 R values per percentage of packet loss
r_actual=$(echo {"($r_value-($effective_latency*2.5))"} | bc -l)

# Convert the R into an MOS value.(this is a known formula)
MOS=$(echo {"1+(0.035)*($r_actual)+(0.000007)*($r_actual)*($r_actual-60)*(100-$r_actual)"} | bc -l)
printf "MOS: %.1f\n" "$(echo $MOS)"

else
echo "Invalid IP Format"
exit 1
fi
  1. Run these commands to change the permission and owner of the shell script:
    $ chmod 500 voip_tcpping.sh
    $ chown serveruser voip_tcpping.sh

Create the Custom Test

Create a Custom Test within the Portal with the JSON template given below.  Make sure that you replace the necessary values.

{
   "shell_command_file_name": "voip_tcpping.sh",
   "host": "10.0.0.1",
   "count": "10"
}

Results

Based on the output that prints on the console, you can create Tracepoints and Indicators to capture the metrics and analyze them in the Portal.

Screen_Shot_2018-09-26_at_11.23.48_AM.png

Now we can set up Insight to capture and analyze the results.

Insight1.png

Insight2.png