0

For improved traceability, accountability, etc., I want certain applications to be supervised by systemd and have their output collected in the journal. I know that this all happens automatically when I use systemd-run's service mode, but due to dependence on the calling environment, this is sometimes not possible.

I have tried using systemd-run and systemd-cat together, but have found that it sadly fails to capture the unit metadata. I know I could theoretically dump the environment variables to a file with env before starting the process and then pass that as EnvironmentFile= to systemd-run, but that seems like a hack. It also fails if there is other data in the execution environment than variables that are needed, such as file descriptors, although that's a relatively rare requirement, as shell pipes, the most common type of shared file descriptor, can usually be replaced with temporary named pipes or files.

I'm not unwilling to use the hacky approach; I'm just wondering if there is a "known good" alternative to it.

EDIT: Since the comments asked, the metadata fields I'm looking for are _SYSTEMD_UNIT, _SYSTEMD_SLICE, etc., as well as _AUDIT_LOGINUID, _CAP_EFFECTIVE, and other such metadata that is usually collected for supervised processes. I found out this is possible for scope units when I was looking at podman/conmon container logs, which have full metadata, despite being manually created using sd_journal_sendv from within a scope unit. I also checked the source code of logger(1) and it uses the same function, so I'm assuming there's something about the unit setup of podman/conmon that enables journald to establish the correlation that isn't there with systemd-run.

3
  • What do you mean by "unit metadata" in this case? Commented Nov 22, 2021 at 15:46
  • What is exactly the output that you want to get from the process? Which metadata are you looking for? You can use systemctl commands, like systemctl show run-<id>.scope to show the properties of the job.
    – aviro
    Commented Nov 22, 2021 at 15:51
  • Added clarification to the question. Commented Nov 22, 2021 at 18:24

1 Answer 1

0

After experimenting further, I have found that layering systemd-run --scope and systemd-cat does properly capture metadata, except for certain edge cases; my testing was simply too narrow and managed to hit exactly those.

To elaborate, there is presumably a race condition between when journald processes the incoming message and when systemd garbage collection cleans up the scope unit after it dies.

In my tests, if I wrapped a longer-running process in these two tools or added a sleep to the end of a one-off command, the journal entries were properly enriched with unit metadata and the like. However, I had to use the "exec" form of systemd-cat, i.e. passing the command to be executed after a --. Piping did not work. I tried opening a shell under systemd-run --scope, executing a command, and piping the output into systemd-cat. Still, even though I included a sleep after the pipeline to avoid the aforementioned race condition, the created journal entries were not enriched with the unit metadata.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .