A production‑ready, multi‑container stack to ingest syslog over UDP/TCP with syslog‑ng, persist logs in MariaDB, and explore them via the LogAnalyzer web UI. It also ships with an optional dbcleanup sidecar to prune old rows and a built‑in logrotate scheduler for file outputs.
This README matches the provided repository snapshot. See
docker-compose.yml(prebuilt images from GHCR) anddocker-compose.dev.yml(build locally) for two usage modes.
- syslog‑ng + MySQL (MariaDB) output
- Listens on UDP/TCP 514, parses Shelly device messages, writes into
SystemEvents. - Healthcheck and optional log rotation via supercronic + logrotate.
- Listens on UDP/TCP 514, parses Shelly device messages, writes into
- MariaDB with one‑time bootstrap from
data/init.sql(schema + indexes + daily OPTIMIZE event). - LogAnalyzer (PHP/Apache) served from
loganalyzercontainer with a bind‑mountedconfig.php. - Cleanup sidecar (
dbcleanup) that deletes old rows on a cron schedule and optimizes the table. - Environment‑driven configuration via
.env. - Multi‑arch images (amd64/arm64) & CI pipeline (lint, build, scan, e2e).
+-------------+ UDP/TCP 514 +------------+ SQL (MySQL) +-----------+
| Clients | ─────────────────▶ | syslog-ng | ────────────────▶ | MariaDB |
+-------------+ +------------+ +-----------+
│ ▲
│ │
└────────── HTTP 80 ─────────────┘
|
+----------+
|LogAnalyzer|
+----------+
Optional: dbcleanup -> runs scheduled DELETE/OPTIMIZE against MariaDBContainers & key files:
syslogng(image:ghcr.io/alaub81/syslogngor built viaDockerfile-syslogng)- Config:
data/syslog-ng/config/*.conf - Entry:
resources/syslogng-entrypoint.sh(renders logrotate, starts supercronic + syslog‑ng)
- Config:
database(image:mariadb:latest)- Init SQL:
data/init.sql(schema, indexes, daily OPTIMIZE event) - Volume:
dbdata(persistent)
- Init SQL:
loganalyzer(image:ghcr.io/alaub81/loganalyzeror built viaDockerfile-loganalyzer)- Config:
data/loganalyzer/config/config.php(bind‑mounted to/var/www/html/config.php)
- Config:
dbcleanup(optional; image:ghcr.io/alaub81/dbcleanupor built viaDockerfile-dbcleanup)- Script:
resources/dbcleanup.sh - Entrypoint:
resources/dbcleanup-entrypoint.sh
- Script:
- Docker Engine 24+ and Docker Compose v2
- Open ports 514/udp and 514/tcp on the host (or customize via
.env) - Outbound access to GHCR/Docker Hub (unless you build locally)
cd /opt
git clone https://github.com/alaub81/syslogserver.git
cd syslogserver
cp .env.example .env
# Edit .env as needed (ports, DB credentials, retention, cron)This uses docker-compose.yml and pulls images from GHCR.
docker compose up -dThis uses docker-compose.dev.yml to build images on your machine.
docker compose -f docker-compose.dev.yml --env-file .env up -d --buildOpen http://localhost:${LOGANALYZER_PORT} (default 8181) and follow the wizard:
- DB Type: MySQL (MariaDB)
- Host:
database· DB:${DB_NAME}· User:${DB_USER}· Password:${DB_PASSWORD} - Source table:
SystemEvents
The file
data/loganalyzer/config/config.phpis bind‑mounted as/var/www/html/config.php; changes persist in your working tree.
See .env.example for documented defaults. Most common settings:
# Timezone inside containers
TZ=Europe/Berlin
# Syslog listener ports on the HOST
SYSLOG_UDP_PORT=514
SYSLOG_TCP_PORT=514
# LogAnalyzer (HTTP) port on the HOST
LOGANALYZER_PORT=8181
# MariaDB credentials
DB_NAME=syslogdb
DB_USER=syslog
DB_PASSWORD=changeMe!
DB_ROOT_PASSWORD=changeRoot! # only used at initial bootstrap
# Log cleanup (dbcleanup container)
LOG_RETENTION_DAYS=30 # delete rows older than N days
DBCLEANUP_CRON=0 3 * * * # daily at 03:00
# syslog-ng file rotation (if file destinations used)
LOGROTATE_CRON=0 * * * * # hourly
LOGROTATE_SIZE=50M # rotate at ~50 MB
LOGROTATE_MAX_AGE_DAYS=14 # delete rotated files older than N days
LOGROTATE_ROTATIONS=7 # keep N rotated files
# Only needed when you like to build localy with docker-compose.dev.yml
# Loganalyzer Version (https://loganalyzer.adiscon.com/download/)
LOGANALYZER_VERSION=4.1.13
# Configure loganalyzers Download-URL (TGZ)
LOGANALYZER_URL=https://download.adiscon.com/loganalyzer/loganalyzer-${LOGANALYZER_VERSION}.tar.gzTip – ServerName warning: If Apache logs
Could not reliably determine the server's FQDN, setServerName(e.g., via a tiny conf) or ignore – it’s harmless.
If you like to have a debug log for the shelly devices or a raw dump log, just copy the disabled config files under ./data/syslog-ng/config/
cp ./data/syslog-ng/config/20-shellylog.conf.disabled ./data/syslog-ng/config/20-shellylog.conf
cp ./data/syslog-ng/config/90-rawlog.conf.disabled ./data/syslog-ng/config/90-rawlog.confand if application is already running, just restart syslogng container:
docker compose restart syslogngFrom another container on the same compose network:
docker run --rm --network $(docker network ls --format '{{.Name}}' | grep syslogserver) debian:trixie-slim bash -lc 'logger -n syslogng -P 514 -d "hello-from-ci-$(date +%s)"'echo "hello-from-nc" | nc -u -w1 127.0.0.1 "${SYSLOG_UDP_PORT}"docker compose exec -T database sh -lc 'mariadb -u"$MARIADB_USER" --password="$MARIADB_PASSWORD" -D "$MARIADB_DATABASE" -e "SELECT COUNT(*) FROM SystemEvents;"'just open up loganalyzer ui with your browser and check if the message appears.
- syslog-ng: checks
syslog-ng-ctl statsor UDP 514 socket accessible. - database: waits until MariaDB is ready & answers SQL.
- loganalyzer: HTTP probe on
/.
If a service is stuck unhealthy, inspect logs:
docker compose logs --no-color syslogng database loganalyzer- Replace all default passwords in
.envbefore exposing ports on public networks. - Restrict inbound 514/udp + 514/tcp to trusted networks.
- Keep images updated (CI can rebuild weekly and on base‑image changes).
docker compose -f docker-compose.dev.yml --env-file .env up -d --build
# Logs
docker compose logs -f --tail=200 syslogngTo run linters locally (optional):
- Dockerfiles:
hadolint - Shell scripts:
shellcheck - YAML:
yamllint
- No rows in DB: check
syslognglogs for SQL errors (credentials, table names). - DeviceReportedTime/ReceivedAt errors: ensure timestamps are passed as
YYYY-MM-DD HH:MM:SSto MariaDB. - Messages also written to files: remove or disable file destinations in
data/syslog-ng/config/*.conf. - LogAnalyzer shows missing columns: confirm your table matches
data/init.sql(e.g.,ProcessID,EventLogType, etc.). - Healthcheck fails for syslog‑ng: ensure
syslog-ng-ctlexists inside the image; optionally installnetcatif you use the fallback.
- License: MIT (see
LICENSE) - Security Policy: see
SECURITY.md(how to report vulnerabilities)
See Git commit history and release notes.