podman in systemd: improve logging

Created on 15 Jun 2020  路  22Comments  路  Source: containers/podman

We need to find a way to easier integrate the container/pod logs into the systemd service and journalctl. At the moment, we run containers with --detached such that stderr and stdout don't show up in the service logs and can only be examined via podman logs.

I guess we need a combination of --log-driver=journald and --log-opt tag=... with the later maybe being set to %n (i.e., the unit/service name).

Cc: @mheon @rhatdan @goochjj @storrgie @lucab

In Progress kinfeature stale-issue

Most helpful comment

In case the perspective of an ignorant end user is at all helpful here: my expectation when I fired up containers via systemd (generated via podman generate systemd) was to see roughly the same output in journalctl as what podman logs shows. Other logs (e.g. slirp4netns) feels like an implementation detail that I wouldn't want to see unless opting in via config or something.

All 22 comments

Not sure if directly useful for podman, but journald has capabilities for distinguishing/isolating logs from (containerized) services:

The first has some known races on exit. The third is a recent feature. The second can be used in conjunction with machinectl (see an example on the defunct rkt docs).

conmon with --log-driver=journald adds CONTAINER_ID, CONTAINER_NAME and CONTAINER_ID_FULL to every log coming from conmon and from the container's stderr and stdout... (and container_tag if specified) Note the CONTAINER_NAME wasn't logged until a merge 27 days ago in #6291 and a related pull in conmon.

The unit identifier should also be logged consistently now that the default is cgroups no-conmon - Journald will get the correct unit context from the cgroup of the process.

conmon internals log via syslog() when --syslog is passed, which ends up on /dev/log, which gets logged to systemd under the correct unit, with any LogExtraFields in the unit file, but without CONTAINER_xxx metadata. (Because only the logs send to the journald socket have the additional CONTAINER_xxx fields)

So with log-driver journald
stderr + stdout -> journald socket, with CONTAINER_xxx metadata
internal logs -> syslog socket (when --syslog, which podman sets), without any CONTAINER_xxx metadata

I'm currently using an OCI hook to write CONTAINER_ID and CONTAINER_ID_FULL into /run/systemd/units/log-extra-fields:unitname, which adds those fields to the internal logs received via /dev/log. I'm also launching a busybox syslogd instance, that binds to /dev/log inside my container and forwards to the host's /dev/log, which also leverages the log extra fields, so everything gets logged right.

Except the journald driver, which nows receives every field twice, so I get CONTAINER_NAME [ "name", "name" ], but it still seems to work for filtering purposes.

Conmon could leverage writing directly to journald in utils.h so the conmon internal logs have more control, instead of writing to /dev/log they'd now write to the journald socket.

It'd be extremely nice to have verbose logging about the overall state of all subsystems related to operating the container (podman/conmon/slirp4netns/etc.) in the standard systemd journal. then the container logs itself being done via a tagging mechanism would be fine.

Unifying the logs would __maybe__ be better for usability. It's not clear (until @goochjj starting posting) that I could find the logging via journalctl CONTAINER_NAME=<name>

Any process spawned by podman would likely log via syslog, and be logged under the systemd unit that spawned podman.

I don't think I agree with your assertion - I'm not sure I agree that utility processes (i.e. podman, conmon, slirp4netns) should identify themselves with the container - they're outside the container. It feels to me like there should be a difference between "inside the container" logs and "outside the container" logs. (Which, based on how conmon is right now, is maintained - conmon logs go to syslog and are attached to the unit, but not the container ID and name, while stderr/stdout from the container ARE tagged properly)

I don't quite know how to accommodate that - by leveraging LogExtraFields I'm attaching that metadata to anything subordinate to the unit.

I don't think I agree with your assertion - I'm not sure I agree that utility processes (i.e. podman, conmon, slirp4netns) should identify themselves with the container - they're outside the container. It feels to me like there should be a difference between "inside the container" logs and "outside the container" logs. (Which, based on how conmon is right now, is maintained - conmon logs go to syslog and are attached to the unit, but not the container ID and name, while stderr/stdout from the container ARE tagged properly)

I agree with you, consistency and transparency of how one has awareness of those two logging streams would really help.

A friendly reminder that this issue had no activity for 30 days.

@vrothberg @goochjj Any progress on this?

We probably need to better flesh out exactly what desired state is before this will be actionable

I concur. Let's put it on our roadmap. I won't find time this week to think this through.

I concur. Let's put it on our roadmap. I won't find time this week to think this through.

I created a card to our internal pipeline to make sure we can tackle it in the future and discuss upstream here what we want and need.

In case the perspective of an ignorant end user is at all helpful here: my expectation when I fired up containers via systemd (generated via podman generate systemd) was to see roughly the same output in journalctl as what podman logs shows. Other logs (e.g. slirp4netns) feels like an implementation detail that I wouldn't want to see unless opting in via config or something.

It seems like generating units for containers created with --log-driver=journald (or changing the ExecStart line to include said flag) is already enough to get journalctl and systemctl to display the container logs associated with that unit. I haven't tested with pod units though.

Assuming pod units are as good, looks like we only need to add this flag to the unit template in order to close this issue?

A friendly reminder that this issue had no activity for 30 days.

In case the perspective of an ignorant end user is at all helpful here: I tried @yangm97's suggestion and that gives me more or less what I was looking for.

Since the play kube command does not have a --log-driver option, this remains a problem for containers created through this command. A --log-driver option to play kube would allow @yangm97's suggestion to work for pods too.

Sounds good, would someone from the community want to open a PR to add this feature?

If no one is working on this already, let me take it

/assign

@andylibrian You got it, thanks.

A friendly reminder that this issue had no activity for 30 days.

I think this is completed now:

  • [x] Generating systemd units for containers created with --log-driver=journald works as expected, logging to journald
  • [x] --log-driver arg has been added to play kube

Ok I will close.

Was this page helpful?
0 / 5 - 0 ratings