External Publication
Visit Post

Monitoring Home Internet Performance with a Raspberry Pi

~/.bnux December 2, 2024
Source

I got mad at my ISP. Now you can get mad at yours with this one simple trick!

I recently noticed a drop in performance with my home internet. Calls have been choppy, videos buffer a lot, and the overall quality of connection has noticeably decreased. I tried troubleshooting things on my local network to the best of my ability but the issues persisted. Even connecting directly to the router, I continued to see high latency#Packet-switchednetworks) and packet loss.

So, like most normal people, I decided to set up a Raspberry Pi to run network tests and collect data to better understand my network issues. I flashed a fresh image of Raspberry Pi OS onto an old 3 Model B+ and decided on a few tools to use for the job: speedtest-cli, mtr, InfluxDB, and Grafana.

I’ll explain how and why I use each below. But the desired outcome is a dashboard where I can identify spikes or trends that indicate ongoing problems with my internet connection. I can share that information with my ISP in an attempt to diagnose and hopefully resolve the issue.

Set Up the RasPi

We’ll first need to prepare our Raspberry Pi. I used Raspberry Pi Imager to start fresh with a clean install of Raspberry Pi OS. If you use the imager, you can follow its prompts to set the hostname, enable SSH access, and configure additional settings. For this use case, make sure to enable SSH so you can login to the Pi remotely.

After the Pi is up and running, you’ll need to connect it to your home network. If possible, I suggest connecting directly to your router via ethernet. By doing so, you can rule out issues related to wireless connectivity.

Once your Raspberry Pi is connected, you can login via SSH with or , where is the hostname or is the IP assigned to your Raspberry Pi. If you are unsure what either of these are, you can run [^1]. That command will return something like the following:

From that response, you can pull the hostname () or the IP (). Then you can connect with .

Install Packages

Once you’re logged in via SSH, you’ll need to install the tools we are going to use. We’ll use , which is included in Raspberry Pi OS, to test latency. We’ll use speedtest-cli to test upload and download speeds. And we’ll use mtr to check for packet loss.

We can store the results from each of these tools using InfluxDB, which is a time series database built to handle metrics, events, and logs. Finally, we’ll use Grafana to create a dashboard to display these results over time and tie everything together.

The Grafana package isn’t currently included in the default Raspberry Pi OS repositories. So we’ll need to add it ourselves:

Now we can update our package list and install Grafana:

We’ve got everything we need installed now and we can start putting it all together.

Set Up InfluxDB

Let’s start the InfluxDB service. This is what we’ll use to create the database that will store our test results. We can start the service and create a database like so:

Set Up Grafana

We’ll use Grafana to visualize and display our data. We’ve installed it above, now we need to start the service and configure it to use the InfluxDB database we just created:

By default, Grafana will use port . You can access the web UI via browser by hostname and port: . Or you can access via IP address and port like so: .

The default login credentials for Grafana are: Username: Password:

Use those to login and you’ll be prompted to set a more secure password. After setting a new password, we can move on to the next step. We’ll return to Grafana a bit later to create the dashboards.

Write the Tests

With everything in place ready to catch our data, we can write our tests. We’ll just use some simple bash scripts for each. Let’s start by writing a script to run our speedtests.

Test Upload and Download Speeds

Raspberry Pi OS ships with GNU nano and vi), so we can use either to create and edit our file. I’ll create and open a new file for our speedtest script with:

In this script we’ll run , capture the results as JSON (this is where we need jq), and then write them to our database. InfluxDB uses port to run its HTTP service by default, so the script assumes we’re using the default settings. I’ve included some basic logging as well, which will help us troubleshoot issues later on if need be.

[!WARNING] You’ll need to update the filepaths in these scripts (e.g. ) to match your directory structure.

To ensure you saved your file (it’s then ) you can [^2] and check the output. That should give you the contents of the file we just created.

With our script created, we need to make it executable so we can run it:

Let’s take it for a test drive with . It may take a minute, but you should see the results of the speedtest after running it manually. Later on, we’ll use cron to schedule it to run automatically.

Test Latency

This might be overkill since can capture . But I wanted to include a dedicated ping test for a couple reasons. A separate test allows me to separate concerns. And since the ping test alone will be lighter than a full speedtest, I can run it more frequently to establish a tighter baseline.

Like our speedtest, let’s create a new file for our ping test with our editor of choice:

Our script as written below will ping Google’s Public DNS at ten times and capture the average round-trip time and jitter. Then it will write those results to the database.

[!INFO] Remember to update the filepaths so they match your directory structure. You can also adjust the count and target IP address if you’d like[^3]

As with the above, we’ll make it executable with . Then we can double check the contents of the file with and take it for a manual test drive with .

Test for Packet Loss by Hop

(My Traceroute) combines the functionality of and into a single network diagnostic tool. It allows you to see latency and packet loss for each hop) along the way to the destination whereas only shows the packet loss to the final destination. This is helpful in determining where packet loss is occurring along the route. You can use to view live results or print them to a report. In our case, we’ll do the latter and store what we need from the reports in our database. First, let’s again create a new script:

In the script, we’ll configure to run and extract packet loss for each hop by IP address. We’ll use the flag to output results as a report which we can then write to the database. Again, you can modify the parameters like count () and target IP address () if you’d like [^3].

And once again, we can check the contents of the file with and make it executable with . Then we can the script manually to test it with .

Schedule the Tests

With our scripts ready, we can use cron to schedule them to run at regular intervals.

[!INFO] You can adjust the timing for each test. For example, I run and every 30 minutes and every 15 minutes. Again, remember to change the path to match your own.

If you’re unsure of the full path for your scripts, you can use to find them. For example, we can find the path for our speedtest script like so:

Connect the Data

With our tests running and populating the database with their results, we can head back to Grafana to create a dashboard to visualize our findings.

Open Grafana again in your browser (e.g. ). First we need to connect Grafana to the datasource, which we created with InfluxDB earlier: On the left, head over to Connections => Add new connection. Select InfluxDB. In the top right, click Add new data source.

Most of the default values should suffice. We just need to add: URL: Database:

Now click Save & test. You should receive confirmation that the datasource is working and measurements were found.

Visualize the Results

With our data source connected, it’s time to create the dashboard. In the top right, click Build a Dashboard and follow these steps: Click Add Visualization. Select Influxdb as the data source. Scroll down to Queries.

You’ll now need to build your query for each metric you want to visualize. For example, we can display results over time from our ping test by creating a panel with two queries. First, we’ll look at ping:

And second, we’ll look at jitter:

You can customize the display options as much or as little as you’d like using the panel on the right. You can add a title, choose the graph style, and set units appropriately. When you’re happy with the look, you can save the panel and create two more for the and test results following a similar process. I landed on the following:

Troubleshooting

It took a little trial and error to get things running smoothly, but here are a few troubleshooting tips that helped me along the way.

Check the logs

We included basic logging for each of our scripts. Those logs are a good place to start to see if there are any errors. For example, we can check the speedtest logs with to see if the script is being run and completed successfully.

If there there aren’t any errors in those logs then we can check the cron logs with . If all is well, we should see entries like the following:

Check File Permissions

If the scripts aren’t running as scheduled, check the file permissions to make sure they are executable. You can check the permissions for all shell scripts with [^4] like so:

If any scripts don’t have execute permissions to run via cron, you can add them like so (where is the script in question):

Run the Scripts Manually

If the permissions look good but tests still aren’t running, you can try testing the scripts manually. From the command line run (where is the script in question) and see if it completes successfully. If it does, you may need to check that the syntax is correct in your crontab. You can use to list current cron jobs. You can make changes with as needed and then restart cron with .

If you receive an error when running the scripts manually, we can rule out cron for now and instead use the error messages to diagnose the issue with script itself. Once the script runs manually without error, restart cron and see if the issue is resolved.

What’s Next?

To date, my network issues persist and my ISP has shown no interest whatsoever in my Grafana dashboard (I know, right?). But it feels good to have my frustration captured with pretty charts and numbers! Eventually my ISP admitted they are experiencing issues with connectivity in my area due to outdated infrastucture that will not be updated soon and thus suggested that I find a new provider. Perhaps not the ideal_ outcome, but hey, at least I’m ready to thoroughly test my new provider’s service.

[^1]: stands for Address Resolution Protocol and is a tool used in network administration to map IP addresses to MAC (Media Access Control) addresses of devices on a local network. When you run , it lists all the entries in the ARP table, showing the IP addresses and their corresponding MAC addresses.

[^2]: is a standard Unix utility) that reads files sequentially and outputs them to standard output. It’s handy to quickly check the contents of a file.

[^3]: For our and tests we’re using which is Google’s Public DNS. We can generally trust that to be reliable. You could also use Cloudflare’s DNS Resolver at or any other reliable host for these tests.

[^4]: is a command to list computer files and directories in Unix and Unix-like operating systems. itself lists files and directories, the flag provides more detailed information, and matches all files ending with in the current directory.

Discussion in the ATmosphere

Loading comments...