Search code examples
godbussystemd

How do I register for systemd service lifecycle events?


I want to be informed about all state changes of service units. I know there is the DBUS API which gives me signals for UnitNew and UnitRemoved, but the semantic is still unclear to me. Also the signals doesn't provide the informations I need.

I'm using go and tried the go-systemd lib from coreos. They provide a way to "subscribe" but it's in fact polling all the unit information available in the system. I do not want to do so every few milliseconds, just to get informed about statechanges.

I also tried the default org.freedesktop.DBus.Properties but I can not get this working.

Please help If you can, I'm out of ideas.


Solution

  • The systemd APIs that contain information about the start or stop of service units are:

    • The systemd journal. You can listen to it by executing journalctl or forwarding it via network to your program or watching for changes to the files on disk. E.g.: execute journalctl --follow -o json-pretty _PID=1 (you can add various filters like UNIT=gdm.service to only get those for one service) and then parse stdout according to the systemd journal json output format to get the journal messages of systemd. Use the MESSAGE_ID to match what the event means and watch for unknown messages to know when an existing message got replaced with a new one. While this might work robustly enough, log messages are not primarily intended as an API. As such I would recommend to use the below options.

    • Linux cgroup notifications as they get generated when systemd uses cgroups to start a service.

    • systemd units via their dependencies (like Wants=)