In my previous post in this Flex series, Absolutely simple metrics with Flex I introduced Ookla's internet Speedtest command line utility and showed you how to pick up the latency, download bps, and upload bps statistics by using a Python script.
Eagle-eyed readers might have noticed a tantalizing element of the command we tested with:
speedtest --accept-license -f csv
That -f csv
(format the output for CSV) implies other formats. And indeed, if you invoke the help option (-h
) you see that multiple output formats are supported:
All the cool kids use JSON for speed testing
It just so happens the Flex integration automatically ingests and proceses JSON information. And since so many tools and techniques we IT practitioners use, from external APIs to internal utilities, have adopted JSON as one of their output options, it’s worth re-visiting this example and re-implementing it with a JSON twist.
In the case of our example, the Speedtest JSON output looks like this:
{"type":"result","timestamp":"2022-10-06T16:01:24Z","ping":{"jitter":0.437,"latency":36.504,"low":35.844,"high":36.886},"download":{"bandwidth":117938053,"bytes":1470439610,"elapsed":15005,"latency":{"iqm":43.484,"low":35.123,"high":64.032,"jitter":2.269}},"upload":{"bandwidth":5125601,"bytes":47343420,"elapsed":9409,"latency":{"iqm":32.715,"low":31.482,"high":133.830,"jitter":1.604}},"packetLoss":0,"isp":"Spectrum","interface":{"internalIp":"192.168.101.116","name":"enp0s31f6","macAddr":"B4:45:06:69:92:03","isVpn":false,"externalIp":"174.100.204.122"},"server":{"id":51155,"host":"speedtest-bd-1.zoominternet.net","port":8080,"name":"Armstrong Cable","location":"North Lima, OH","country":"United States","ip":"72.23.2.122"},"result":{"id":"5246f9b4-d5dd-4205-8ea2-427bcdda747a","persisted":false}}
In many ways, this version is much simpler than the script-based version in my Absolutely simple metrics post. I'll call out some of the key elements of this YAML file:
interval: 1h
As with the script-based version, we don't want to saturate our bandwidth with tests every few minutes, so setting the interval to once per hour seems reasonable. Feel free to "salt to taste."
- run: speedtest --accept-license -f json
Here's the actual command we're running, with JSON specified (not .jsonl* or .jason-pretty):
timeout: 300000
As with the script-based version of this monitor, running Speedtest takes more than the default 30 seconds, so we need to extend the running time to allow for it. Five minutes (500000 milliseconds) has worked fine in my tests.
Getting set up
To quickly review, here's what you'll need to do before you start this tutorial:
- Have a New Relic account. (The free one will work fine!)
- Install the New Relic infrastructure agent as I described in Absolutely simple Flex.
- Install the Ookla Speedtest utility.
YAML lama ding dong
With those particulars out of the way, now we're ready to set up our YAML file in /etc/newrelic-infra/integrations.d
(or C:\Program Files\New Relic\newrelic-infra\integrations.d
if you're testing this on a Windows system).
integrations:
- name: nri-flex
timeout: 5m
interval: 1h
config:
name: linuxspeedtest
apis:
- name: speedtest
commands:
- run: speedtest --accept-license -f json
timeout: 300000
remove_keys:
- timestamp
If you look back at the sample JSON output, you'll notice one of the first items is a timestamp. Left in place, this could conflict with the New Relic internal time marker during ingest, so we're better off removing it using the remove_keys
function.
remove_keys:
- timestamp
For details on supported YAML functions (like this remove_keys
option) check out this document on data parsing and transformation functions. For information on other commands and switches, see our documentation on Flex YAML options.
No, I didn't know what "JSONL" format was either. But running it once showed me quickly—it's a list of each test as it executes. Great for tracking progress, but not so good for metric collection.
Now add the NRQL
After your YAML file is set up and running, data should be flowing into your New Relic account. To see it, let's start again with the very high-level query:
FROM speedtestSample select *
This will show all of the JSON information we're collecting:
If you scroll right, you'll find values for Download.Bandwidth
, Download.Bytes
, Download.Latency
, Upload.Bandwidth
, and more. This should be everything you need, with one hitch: in the script-based version of this monitor, we were able to divide the download number by 125,000 to get the bits per second (bps) value before presenting that output to New Relic for ingest.
In this case, because we're taking the unprocessed JSON data, we'll have to post-process it. Therefore, our final NRQL query will look like this:
FROM speedtestSample select average(download.bandwidth)/125000, average(upload.bandwidth)/125000 TIMESERIES
That query, when turned into a chart, makes a lovely addition to the system's dashboard:
I hope you've enjoyed our Flex journey together over the course of this blog series. If you have any questions or comments, we’d love to hear from you in the New Relic Community Slack where you can join other developers and the New Relic team in great conversations on this topic and many others!
Próximos pasos
- For more configurations of Flex, read our documentation.
- Missed an earlier blog in this four-part series?
- Learn what Flex is in part one.
- Find out how to ingest and visualize your custom data in part two.
- Set up simple metrics with Flex in part three.
- On Reddit? Join us December 14, 2022 on r/DevOps for an AMA (Ask Me Anything).
Las opiniones expresadas en este blog son las del autor y no reflejan necesariamente las opiniones de New Relic. Todas las soluciones ofrecidas por el autor son específicas del entorno y no forman parte de las soluciones comerciales o el soporte ofrecido por New Relic. Únase a nosotros exclusivamente en Explorers Hub ( discus.newrelic.com ) para preguntas y asistencia relacionada con esta publicación de blog. Este blog puede contener enlaces a contenido de sitios de terceros. Al proporcionar dichos enlaces, New Relic no adopta, garantiza, aprueba ni respalda la información, las vistas o los productos disponibles en dichos sitios.