OK, so syncthing is cool for automatic synchronization and backups and all of that stuff. But there are also times when you open the web UI and notice that no data transfer has happened within the last two months. Nice!
This is often caused by faulty run conditions that can be set in the app or network errors. The syncthing server may also have some trouble, too. I’ve decided to create a little bot with the goal to monitor sync progress and to send out alerts in case of failure. I’m using a Telegram bot to get notified. In a previous post, I’ve described how to create such a Telegram bot.
The bot uses the syncthing REST API to check the lastSeen
timestamp of each device and compares it to the current date and time. It then sends out the lastSeen
value and the time delta. Of course, it’s also possible to create an alert in case the time delta is greater than a few days.
OK What’s Required?
- A syncthing API key
- The device identifier for each device that’s going to be monitored. You can get these identifiers using the web UI.
- If you’re using Telegram: The bot API token and the chat ID.
Give Code Please
#!/usr/bin/env python3
import requests
import time
from datetime import datetime, timedelta
# map device names to syncthing identifiers
DEVICES = {
"bananaphone":
"YOLOBOI-[...]-[...]-[...]-[...]-[...]-[...]-[...]"
}
HEADERS = {"X-API-Key": "[Syncthing API key]"}
TOKEN = "[Telegram bot token]"
CHATID = "[Telegram Chat ID]"
PARAMS = {"chat_id": CHATID}
while True:
r = requests.get("https://[...]/rest/stats/device",
headers=HEADERS)
j = r.json()
for device in DEVICES.items():
ID = device[1]
lastSeen = j[ID]["lastSeen"]
# high quality parsing
tsLastSeen = datetime.strptime(lastSeen.split("T")[0], "%Y-%m-%d")
daysDelta = (datetime.now() - tsLastSeen).days
sendStr = "%s: %s (%d)" % (device[0], lastSeen, daysDelta)
_tmpParams = dict(PARAMS)
_tmpParams["text"] = sendStr
requests.get("https://api.telegram.org/bot%s/sendMessage" % (TOKEN), params=_tmpParams)
# one day
time.sleep(86400)
Deploying the Bot
I’m using this Dockerfile
to run this thing:
FROM debian:latest
RUN apt update && \
apt -y install python3 python3-pip && \
pip3 install pipenv
COPY . /opt/syncthing-monitor
WORKDIR /opt/syncthing-monitor
RUN pipenv --python 3 && \
pipenv install requests
HEALTHCHECK --interval=60m --timeout=5s CMD curl --fail -k [syncthing instance] || kill 1
CMD pipenv shell python3 /opt/syncthing-monitor/monitor.py