Monitor paths with Systemd

After experimenting with AWS S3 triggering events on PutObject it is time to revisit and document event triggering in Systemd.

In the past I used this to trigger an image recognition on an uploaded image in a folder. This is done using systemd-path. Two systemd config files are needed. One is monitoring a path and the other one is the service that is executed when the first one is firing. Assume we have a folder that watches on images uploaded and triggers a script when a new image is added.

First watch the /somewhere/inbox folder on changed files:

[Unit]
Description=watch inbox folder on changes

[Path]
PathChanged=/somewhere/inbox
Unit=process-image.service

[Install]
WantedBy=multi-user.target

The parameter in Unit is the service that is called on change. This service could look like this:

[Unit]
Description=Run image processing

[Service]
Type=simple
ExecStart=/somewhere/processing.sh

[Install]
WantedBy=multi-user.target

Both files have to live in /etc/systemd/system/ (or a symlink from there to a versioned folder). Now activate the two systemd configs:

sudo systemctl enable image.path image.service
sudo systemctl start image.path

The filename is not send to the service, so the service has to glob in the watched folder for the new files and should start processing by moving the file. The possibility of processing a file twice is still there if two events are triggered too fast. The triggering default limit is "2 seconds" between events. This can be changed with TriggerLimitIntervalSec= and TriggerLimitBurst=. Processing an image twice would be no problem and it is very unlikely to happen, because the rate images are added is currently one per hour.

An example for the processing script may look like this:

#!/bin/sh

IN=/somewhere/inbox
OUT=/somewhere/processing
mkdir $OUT
for fn in $(find $IN -type f); do
   mv ${fn} $OUT/
   base_fn=$(basename $fn)
   echo "process: $base_fn"
   python process.py $OUT/$base_fn
done

Everything written to stdout (echo, print, ...) can be seen in systemd journal, i.e. journalctl -u image.