Ronde, a simple monitoring service

As seen in a previous post, I’m running Gentoo on various servers. I wanted a simple way to monitor them and know when one of the service I needed is down.

Tools I considered

I stumbled upon various tools:

Successful proof of concept

I wrote a small proof of concept in Rust that would run some commands and generate a status page based on their output.

It was very easy to write with Tokio and I was happy with the result. I decided to make it a bit more polished and released it as Ronde.

How does it work ?

Ronde is run every X minutes by a cron job. It reads a configuration file that is written in TOML. It looks like this:

## Ronde configuration file

# Name of the Ronde instance, used in the HTML output
name = "Ronde"
# Where to store the HTML output
output_dir = "/var/lib/ronde/html"
# Where to store the history file
history_file = "/var/lib/ronde/history.json"

## Default environment variables for all commands
[default_env]
# If present, the command will be run as this user
uid = 65534 # nobody
# If present, the command will be run as this group
gid = 65534 # nogroup
# If present, the command will be run from this directory
cwd = "/tmp"
# If set to true, clear the environment variables before running the command
clear_env = true
# If present, the command will be run with these environment variables set
env.PATH = "/usr/local/bin:/usr/bin:/opt/bin"
env.USER = "nobody"
env.HOME = "/home/nobody"
env._ = "/usr/bin/env"

## List of commands to run

[[commands]]
# Name of the command, used in the HTML output
name = "ping localhost"
# Command to run
run = "ping -c 4 localhost"
# Consider the command a failure if it takes more than this many seconds
timeout = 5

[[commands]]
name = "ping hits timeout"
run = "ping -c 10 localhost"
timeout = 5

[[commands]]
name = "ping google.com"
run = "ping -c 4 google.com"
timeout = 5

[[commands]]
name = "ping6 google.com"
run = "ping6 -c 4 google.com"
timeout = 5

Every command is run in a separate process and the output is stored in the history file.

Based on the output of the commands, Ronde generates an HTML page that shows the status of this run and the history of the previous runs. It aggregates the history of the commands over up to a week.

It also sends a notification if a command fails. It uses the Pushover API to send notifications. It is cheap and works well. I use it to send notifications to my phone.

The Status page

At first, I wanted to a single page that would hold all the information. I used Maud in the proof of concept but given all the output of the commands was held, the page was getting quite big and long to open. I decided to have a simple HTML page that would load JSON data as needed. It only using native JavaScript and CSS with no dependencies.

On the CSS part, I made it responsive and it looks good on a phone. It also has a dark mode based on the user’s preference.

The colorscheme is based on the gruvbox colorscheme.

Security

I tried to limit the attack surface of Ronde. It can run as an unprivileged user and every command is run in a separate process with a limited environment.

What does it look like?

I host a sample instance of Ronde at fau.re/ronde.sample/.