[WiP]Simple uptime monitor with SVG rendering, Lua protocol handling, and no BS
  • Go 84.9%
  • Lua 15.1%
Find a file
2026-04-14 09:50:03 -07:00
builtin fix IMAP plugin for API change 2026-04-06 15:07:01 -07:00
.gitignore draft: add first stuff and example config and example scripts 2026-04-05 19:05:57 -07:00
config.sample.toml doc update 2026-04-14 09:50:03 -07:00
files.go finish testing, now works 2026-04-06 12:19:28 -07:00
go.mod add services and build instructions 2026-04-06 15:40:02 -07:00
go.sum finish testing, now works 2026-04-06 12:19:28 -07:00
handler.go fix readme, gofmt 2026-04-06 15:00:06 -07:00
LICENSE Initial commit 2026-04-05 16:41:45 -07:00
main.go fix readme, gofmt 2026-04-06 15:00:06 -07:00
README.md doc update 2026-04-14 09:50:03 -07:00

swuptime

Simple uptime monitor with SVG rendering, Lua protocol handling, and no BS

Configuration

The config.sample.toml file already makes an example of a fully working swuptime instance with an HTTPS site and an SMTP server.

# These global settings can be overridden anywhere

# Already default
#image = "builtin://status.svg"
#interval = 15
#timeout = 5
#tls = false

# Needs setting, either here or in a specific site config
#port = 1234
host = "example.com" # example.com everywhere unless overridden
path = "/var/www/stats/$NAME.svg" # Places SVGs here, $NAME is replaced by the name of the site config, i.e. /var/www/stats/website.svg and /var/www/stats/email.svg

[website]
# I know you need that HTTPS!
port = 443
tls = true
timeout = 2
# Pings https://example.com/health
script = "builtin://http.lua?path=/health" # builtin:// is for scripts embedded in the executable, when using a script path, specify the path without builtin://

[email]
port = 25
script = "builtin://smtp.lua

The configuration only consists of 8 options (yes, eight!), 6 of which already have defaults, and all of them can be overriden in a site config

name type purpose default
interval integer Amount of seconds before making another request and saving SVG 15
timeout integer Amount of seconds to take for TCP to connect until assuming it's down 5
tls boolean Use SSL/TLS for connecton false
host string Host to connect to
port integer TCP port to connect with
image string Path of the original SVG to edit "builtin://status.svg"
path string Path of the new SVGs for status report, $NAME is replaced with the site config's name "images/$NAME.svg"
script string Path of the Lua script to be used for protocol handling "builtin://connect.lua"

URLs

For script and image, builtin:// URLs are special for loading files that are included in the executable.

To see built-in scripts, see Scripts.

To specify parameters, you need to use query parameters like you do in HTTP, e.g. builtin://http.lua?host=foo.bar&path=/lorem/ipsum

Scripts

builtin://connect.lua

Simply does nothing and returns Ok if TCP even connected

No parameters offered

builtin://smtp.lua

Connects to an SMTP server, sends HELO swuptime and then QUITs

No parameters offered

builtin://imap.lua

Connects to an IMAP server, sends A001 NOOP and logs out

No parameters offered

builtin://http.lua

Connects to an HTTP server that supports HTTP/1.1 (hopefully yours does)

Parameters:

name purpose default
host Value of the Host header that's going to be sent to the server host option in config
path Path where the script is going to GET from /
ignore Set to y if it should ignore status codes that aren't 2xx n

Building

Requires Go 1.24 or newer

go build .

Making a portable build

CGO_ENABLED=0 go build -ldflags "-s -w" .

Running

To run temporarily use

./swuptime config.toml
Systemd
[Unit]
Description=Swuptime monitor
After=network.target
Wants=network-online.target

[Service]
Type=simple
# User=swuptime
ExecStart=/path/to/swuptime /path/to/config.toml
Restart=on-failure

[Install]
WantedBy=multi-user.target
OpenRC
#!/sbin/openrc-run

# command_user="swuptime"
command="/path/to/swuptime"
command_args="/path/to/config.toml"
command_background="yes"
pidfile="/run/$RC_SVCNAME.pid"
depend() {
        need net
        use dns
}
FreeBSD rc
#!/bin/sh

# PROVIDE: swuptime
# REQUIRE: NETWORKING
# KEYWORD: shutdown

. /etc/rc.subr

name="swuptime"
rcvar="swuptime_enable"
start_precmd="swuptime_precmd"
procname="/path/to/swuptime"
pidfile="/var/run/${name}.pid"

load_rc_config $name

: ${swuptime_enable:="NO"}
# : ${swuptime_user:="swuptime"}

command="/usr/sbin/daemon"
command_args="-f -l daemon -s info -p ${pidfile} /path/to/swuptime /path/to/config.toml"

swuptime_precmd() {
        if [ ! -e "${pidfile}" ]; then
                install -o "${swuptime_user}" -g "wheel" "/dev/null" "${pidfile}"
        fi
}

run_rc_command "$1"

For services, it's recommended to put swuptime in /usr/local/bin/ and config.toml in /etc/swuptime/

Lua API

The API is fairly simple, it must exit successfully in order to be considered up, simply use error("my reason") to report a problem with the server

The conf table is available to get any of the 8 options defined in the site's configuration.

For security, the os, io, and package modules are removed here.

The following functions are available

get(param string, fallback string)

Returns a string

Gets a parameter from the script URL, otherwise returns the fallback value

socket.get(n integer)

Returns a string or nil

Gets n bytes from the socket

This will return nil if an error occurred, otherwise this will return the received bytes from the server converted to a string.

socket.send(message string)

Returns nil or a string

Sends a UTF-8 message to the server

If an error occurred, this will return a string describing the error, otherwise this will return nil