📜Bash Script to Log Packet Loss via mtr⚗️

Ronald BartelsRonald Bartels
2 min read

The script below attempts to pick up packet loss issues to a destination IP address over a longer period while still measuring the loss over a count of 100 packets.

It logs the anomalies which can then be shared.

#!/bin/bash

# Ensure the script is run with a target IP/hostname as an argument
if [ -z "$1" ]; then
   echo "Usage: $0 <target>"
   exit 1
fi

# Variables
TARGET=$1 # Get target from the command line
PING_COUNT=200
ITERATIONS=1000
LOSS_THRESHOLD=${2:-2}  # Packet loss threshold, default is 2% if not provided
DAY_OF_WEEK=$(date +%A) # Get the current day of the week (e.g., Monday)
LOG_FILE="/tmp/mtr_report_${TARGET}_${DAY_OF_WEEK}.log" # Log file in /tmp directory

# Function to check packet loss of the last hop and log the full mtr report if necessary
check_packet_loss_or_path_change() {
    # Run mtr and capture the full output
    MTR_OUTPUT=$(mtr -r -c $PING_COUNT $TARGET)
    echo "$MTR_OUTPUT"

    # Extract the packet loss percentage of the last hop
    LOSS_PERCENT=$(echo "$MTR_OUTPUT" | tail -n 1 | awk '{print $3}' | sed 's/%//')
    echo "Actual: $LOSS_PERCENT"
    echo "Threshold: $LOSS_THRESHOLD"

    # Extract the previous hop's IP addresses (excluding the last hop)
    CURRENT_PATH=$(echo "$MTR_OUTPUT" | awk '{print $2}' | head -n -1 | tail -n +2)
    echo "Path: $CURRENT_PATH"

    # Check if a path change occurred by comparing the current path with the previous one
    if [ "$CURRENT_PATH" != "$PREVIOUS_PATH" ]; then
       PATH_CHANGED=true
       echo "Path changed!"
    else
       PATH_CHANGED=false
    fi

    # If packet loss is greater than loss linit, or if there's a path change, log the full mtr report with timestamp
    if (( $(echo "$LOSS_PERCENT > $LOSS_THRESHOLD" | bc -l) )) || [ "$PATH_CHANGED" = true ]; then
       echo "Logging MTR output."
       echo "--------------------------------------" >> $LOG_FILE
       echo "$(date): Packet loss on last hop ($LOSS_PERCENT%) or path change detected" >> $LOG_FILE
       echo "$MTR_OUTPUT" >> $LOG_FILE
       echo "--------------------------------------" >> $LOG_FILE
    fi
    # Store the current path as the previous path for the next iteration
    PREVIOUS_PATH=$CURRENT_PATH
}

# Initialize the previous path as an empty string for the first run
PREVIOUS_PATH=""

# Main loop to run mtr 1000 times
for ((i=1; i<=$ITERATIONS; i++)); do
   echo "Running mtr iteration $i for target $TARGET..."
   check_packet_loss_or_path_change
done

echo "Completed $ITERATIONS iterations of mtr."
10
Subscribe to my newsletter

Read articles from Ronald Bartels directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ronald Bartels
Ronald Bartels

Driving SD-WAN Adoption in South Africa