I don't know if it is appropriate or not, but I used the sd-bus library.
I just ask systemd if my service is running. If it is running I then
get the service's MainPID. If the mainPID matches my process pid then
I started from the systemd. If not then I didn't.

I only use it for debugging. If I started it from command line when I
debug I want logging to go to a file. If it started from systemd it
goes to journal. That is the extent of my usage.

The top level logic looks like:

const std::string systemd_destination = "org.freedesktop.systemd1";
const std::string systemd_quietwind_service_path = 
"/org/freedesktop/systemd1/unit/quietwind_2eweather_2eservice";
const std::string systemd_unit_interface = "org.freedesktop.systemd1.Unit";
const std::string systemd_service_interface = 
"org.freedesktop.systemd1.Service";

/*
    * If we have started from systemd then we always use
    * LOGGER_MODE_JOURNAL.
    */
  SdUnit sd_qw_unit(systemd_destination,
                       systemd_quietwind_service_path,
                       systemd_unit_interface);
  SdServiceUnit sd_qw_service_unit(systemd_destination,
                       systemd_quietwind_service_path,
                       systemd_service_interface);

  service_state = sd_qw_unit.getSubState();
  if (service_state.has_value() != true) {
    logger.log(LOG_ERR, "Can't get substate of quietwind weather service");
    exit(1);
  }

  service_pid = sd_qw_service_unit.getMainPID();
  if (service_pid.has_value() != true) {
    logger.log(LOG_ERR, "Can't get main pid of quietwind weather service");
    exit(1);
  }

  if (service_state == "running" && service_pid == getpid()) {
    in_systemd = true;
  }

  if (in_systemd == true) {
    logger.setMode(LOGGER_MODE_JOURNAL);
    logger.log(LOG_INFO, "Logging in Journal Mode");
  }

It took a while to figure out the naming structure. But after that getting
properties and executing commands is not so difficult. I used these pages
to figure it out:

Information about sd-bus library can be found here.
https://www.freedesktop.org/wiki/Software/dbus/
https://www.freedesktop.org/software/systemd/man/latest/sd-bus.html
https://0pointer.net/blog/the-new-sd-bus-api-of-systemd.html
https://manpages.ubuntu.com/manpages/bionic/man1/busctl.1.html
https://www.freedesktop.org/software/systemd/man/latest/org.freedesktop.systemd1.html

Thanks
Chris

On 6/30/25 5:25 AM, Stef Bon wrote:
Hi,

it's important for a program to detect it has been started by systemd.
For example it does not have to fork since it has already been forked.

I've written a test script, which calls env, and there are a few
unique environment variables which are an indication it has been
started by systemd: SYSTEMD_EXEC_PID and INVOCATION_ID.

Is it a good way to test these environment vars (to detect started by
systemd) or is there a better way?

S. Bon

Reply via email to