DMN/Software

ProjectsStatus monitor

Status monitor

A self-hosted uptime and status monitor written in Go. It checks websites, TCP ports and FiveM servers, shows availability and response times publicly and sends a mail when a service goes down and when it is back.

Status page headed All services reachable, updated 17:21, below it the four services Website, Bewerbungsportal, Bewerbungen-API and the source chat, all reachable, each with an HTTP check and a bar of the last hours. Under Incidents the resolved website incident
The public status page on 23 September 2026, below it the most recent resolved incident.

Key facts

As of

Targets
4 on the public status page
Availability since monitoring began on 17 September
Website 99.77 %, job finder 100.00 %, job finder API 99.98 %, source chat 100.00 %
Tests
142 test functions in 31 files

One hiccup is not an outage

An incident only starts after several failed checks in a row. The number can be set per target, the default is three. A single timeout stays a data point and raises no alert.

When the incident starts, a mail goes out. Once the target responds again, the incident ends, and a second mail says how long the outage lasted.

Sketch of a sequence, no measured data.

One goroutine per target

Every target runs in its own goroutine with its own interval. A random offset keeps all checks from starting at the same moment. No more than eight run at once, the rest wait for a free slot.

HTTP(S) checks whether the status code is in the allowed range and optionally a keyword in the response body. TCP only checks whether the port accepts a connection.

For FiveM servers the monitor queries info.json and players.json of the FXServer. It stores the player count, the maximum and the version, never player names.

  1. Goroutine waits for its interval, with a random offset
  2. Slot opens up, at most eight checks run at once
  3. Check over HTTP(S), TCP or FiveM
  4. SQLite stores the result and response time

Status page and admin

For every target the status page shows availability over 24 hours, 7 days and 30 days, a bar of the last 90 hours and the response time history. Addresses and error messages never appear there. The page is available in German and English.

The charts are rendered as SVG on the server. Raw data is kept for 30 days and rolled up into hourly values.

Targets and incidents are managed in a separate admin interface behind a login.

Security

The monitor requests addresses entered in the admin interface. To keep that from reaching the internal network, what counts is the IP after name resolution, not the hostname.

Technology

Language
Go with net/http, html/template and embed from the standard library
Data
SQLite without CGO through modernc.org/sqlite
Charts
SVG, rendered on the server
Operations
a single binary in a distroless Docker image, read-only file system
CI
GitHub Actions with go test -race, golangci-lint and govulncheck

Live