Logging and Health Checks
Syncthing logs all events to the systemd journal. Knowing how to extract meaningful signals — sync completions, errors, connection events — is essential for maintaining a reliable sync mesh.
Learning Focus
Build actionable health checks from Syncthing's REST API and journal output that can be wired into cron, systemd timers, or monitoring tools like Prometheus.
Tool Snapshot
| Log Source | Command | Use Case |
|---|---|---|
| Systemd journal | journalctl --user -u syncthing | General event stream |
REST API /rest/system/status | curl localhost:8384/rest/system/status | Machine-readable health |
REST API /rest/events | curl localhost:8384/rest/events | Structured event stream |
REST API /rest/db/status | curl localhost:8384/rest/db/status?folder=ID | Per-folder sync status |
Reading Logs
read-logs.sh
# Last 100 lines
journalctl --user -u syncthing -n 100
# Since last boot
journalctl --user -u syncthing -b
# Follow in real time
journalctl --user -u syncthing -f
# Filter by log level (ERR and above)
journalctl --user -u syncthing -p err
# Search for specific events
journalctl --user -u syncthing | grep -E "Connected|Disconnected|conflict|error"
Setting Log Verbosity
Syncthing uses --logflags and environment variables to control verbosity:
verbose-launch.sh
# Extra verbose output for debugging (not for production)
STLEVEL=verbose syncthing serve --no-browser --logflags=3
# Suppress timestamps (useful when journald adds its own)
syncthing serve --no-browser --logflags=0
In the systemd unit, set environment:
override — verbose logging
[Service]
Environment=STLEVEL=verbose
REST API Health Checks
healthcheck-api.sh
# Get an API key first (from GUI: Actions → Settings → API Key)
STKEY="your-api-key-here"
# System status (version, uptime, memory)
curl -fs -H "X-API-Key: $STKEY" https://localhost:8384/rest/system/status \
--cacert ~/.local/share/syncthing/https-cert.pem | jq '{version:.version, uptime:.uptime, mem:.sys}'
# Per-folder sync status
FOLDER_ID="docs-sync"
curl -fs -H "X-API-Key: $STKEY" \
"https://localhost:8384/rest/db/status?folder=$FOLDER_ID" \
--cacert ~/.local/share/syncthing/https-cert.pem \
| jq '{state:.state, errors:.errors, need:.needBytes}'
# List connected devices
curl -fs -H "X-API-Key: $STKEY" \
https://localhost:8384/rest/system/connections \
--cacert ~/.local/share/syncthing/https-cert.pem \
| jq '.connections | to_entries[] | {id:.key, connected:.value.connected}'
Writing a Health Check Script
/usr/local/bin/syncthing-healthcheck.sh
#!/bin/bash
# Syncthing health check — exit 0 = healthy, exit 1 = unhealthy
set -euo pipefail
STKEY="${SYNCTHING_API_KEY:-}"
BASE="https://localhost:8384"
CERT="$HOME/.local/share/syncthing/https-cert.pem"
if [[ -z "$STKEY" ]]; then
echo "ERROR: SYNCTHING_API_KEY not set"
exit 1
fi
STATUS=$(curl -fs -H "X-API-Key: $STKEY" "$BASE/rest/system/status" --cacert "$CERT" 2>/dev/null) || {
echo "CRITICAL: Syncthing REST API not reachable"
exit 1
}
UPTIME=$(echo "$STATUS" | jq '.uptime')
echo "OK: Syncthing running — uptime ${UPTIME}s"
# Check all folders for error state
FOLDERS=$(curl -fs -H "X-API-Key: $STKEY" "$BASE/rest/config/folders" --cacert "$CERT" | jq -r '.[].id')
for FOLDER in $FOLDERS; do
STATE=$(curl -fs -H "X-API-Key: $STKEY" "$BASE/rest/db/status?folder=$FOLDER" --cacert "$CERT" | jq -r '.state')
if [[ "$STATE" == "error" ]]; then
echo "WARNING: Folder $FOLDER is in error state"
exit 1
fi
done
echo "OK: All folders syncing normally"
exit 0
chmod +x /usr/local/bin/syncthing-healthcheck.sh
export SYNCTHING_API_KEY="your-api-key"
/usr/local/bin/syncthing-healthcheck.sh
Scheduled Health Check with systemd Timer
/etc/systemd/system/syncthing-health.service
[Unit]
Description=Syncthing Health Check
After=syncthing@syncthing.service
[Service]
Type=oneshot
User=syncthing
Environment=SYNCTHING_API_KEY=your-api-key
ExecStart=/usr/local/bin/syncthing-healthcheck.sh
/etc/systemd/system/syncthing-health.timer
[Unit]
Description=Run Syncthing health check every 5 minutes
[Timer]
OnBootSec=60s
OnUnitActiveSec=5m
Unit=syncthing-health.service
[Install]
WantedBy=timers.target
sudo systemctl enable --now syncthing-health.timer
sudo systemctl list-timers | grep syncthing
Key Log Events to Monitor
| Log Pattern | Meaning | Action |
|---|---|---|
conflict copy | Sync conflict created | Review conflict file, investigate cause |
ERROR: ... permission denied | File permission issue | Fix ownership with chown |
Stopping syncthing | Syncthing shut down | Check systemd restart, investigate crash |
Connected to | New peer connection | Normal operation |
Disconnected from | Peer went offline | Monitor frequency — may indicate network issue |
STUN error | NAT traversal failed | Verify UDP port 22000 is open |