Commit 9222beb2 authored by Anton Sarukhanov's avatar Anton Sarukhanov

Add Zabbix Sound Level blog post.

parent 9f37f7bb
Title: Measuring sound level with Zabbix
Description: Test consumer electronics with enterprise tools!
Date: March 22, 2019
Cover: /media/zabbix/graph-real.png
Featured_Project: true
Here's a way to observe sound level from a microphone using an IT monitoring system.
# Why?
- I wanted to measure how long an old MP3 player could play until the battery died
- ...without having to listen to the music
- ...and I wanted to find out as soon as it stopped playing.
![Photo](/media/zabbix/photo.jpg)
# Zabbix
Zabbix is an open-source monitoring tool. I already use it to keep an eye on my servers. Maybe it can help here?
# Measuring volume
We can use the [`rec` tool](https://linux.die.net/man/1/rec) (part of the [SoX](http://sox.sourceforge.net/) audio processor) to grab audio from the microphone and analyze it.
```bash
rec -n stat trim 0 .5
```
- `-n`: record to `null` instead of a file
- `stat`: calculate statistics
- `trim 0 .5`: record `.5` seconds from the start (`0`)
We can use the `Maximum amplitude` statistic to infer whether the music is playing.
```bash
rec -n stat trim 0 .5 2>&1 | awk '/^Maximum amplitude/ { print $3 }'
```
All that's left is to track this value over time, and alert us when it falls below some threshold.
# zabbix_sender
Zabbix can observe metrics in a few different ways (agent, remote network-based checks, etc).
Here, I just want the easiest way to watch a numeric value with minimal configuration overhead.
Seems like a job for [zabbix_sender](https://www.zabbix.com/documentation/current/manpages/zabbix_sender).
This is the syntax:
```bash
zabbix_sender -z <zabbix-server> -s <monitored-host> -k <metric> -o <value>
```
First, some housekeeping on the Zabbix server:
1. Create a **Host**. Let's call it `soundmonitor`. ![Host](/media/zabbix/host.png)
2. Create a new **Item** for the `soundmonitor` host. Let's call it `soundlevel`. ![Item](/media/zabbix/item.png)
3. Put the Item on a **Graph**. ![Graph](/media/zabbix/graph.png)
Now we can test the `zabbix_sender` command.
```bash
zabbix_sender -z zabbix.example.net -s soundmonitor -k soundlevel -o "0.5"
```
Take a look at the graph. It should now have our fake datapoint!
![Graph 0.5](/media/zabbix/graph-0.5.png)
# All together
We can use [command substitution](https://www.gnu.org/software/bash/manual/html_node/Command-Substitution.html) to string together a one-liner.
```bash
zabbix_sender -z zabbix.example.net \
-s soundmonitor \
-k soundlevel \
-o "$(rec -n stat trim 0 .5 2>&1 | awk '/^Maximum amplitude/ { print $3 }')"
```
This takes the numeric sound level from the `rec|awk` combination and passes it as the `-o` argument of `zabbix_sender`.
Now, we just need to put this in a loop...
```bash
while true; do
zabbix_sender -z zabbix.example.net \
-s soundmonitor \
-k soundlevel \
-o "$(rec -n stat trim 0 .5 2>&1 | awk '/^Maximum amplitude/ { print $3 }')";
done
```
# Ta-da!
![Graph (for real)](/media/zabbix/graph-real.png)
Pausing the iPod produced that valley in the middle. Based on this test, I set a **Trigger** for `soundlevel` falling below `0.5` for 60 seconds or longer.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment