journald logs: keep reading until the journal's end

When reading logs from the journal, keep going after the container
exits, in case it gets restarted.

Events logged to the journal via the normal paths don't include
CONTAINER_ID_FULL, so don't bother adding it to the "history" event we
use to force at least one entry for the container to show up in the log.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
This commit is contained in:
Nalin Dahyabhai 2021-11-12 11:15:18 -05:00 committed by Matthew Heon
parent 76ada2c011
commit 08bcd60c8f
2 changed files with 31 additions and 4 deletions

View file

@ -37,9 +37,11 @@ func (c *Container) initializeJournal(ctx context.Context) error {
m := make(map[string]string)
m["SYSLOG_IDENTIFIER"] = "podman"
m["PODMAN_ID"] = c.ID()
m["CONTAINER_ID_FULL"] = c.ID()
history := events.History
m["PODMAN_EVENT"] = history.String()
container := events.Container
m["PODMAN_TYPE"] = container.String()
m["PODMAN_TIME"] = time.Now().Format(time.RFC3339Nano)
return journal.Send("", journal.PriInfo, m)
}
@ -95,6 +97,7 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
// exponential backoff.
var cursor string
var cursorError error
var containerCouldBeLogging bool
for i := 1; i <= 3; i++ {
cursor, cursorError = journal.GetCursor()
hundreds := 1
@ -173,7 +176,7 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
doTailFunc()
}
// Unless we follow, quit.
if !options.Follow {
if !options.Follow || !containerCouldBeLogging {
return
}
// Sleep until something's happening on the journal.
@ -202,11 +205,14 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
logrus.Errorf("Failed to translate event: %v", err)
return
}
if status == events.Exited {
switch status {
case events.History, events.Init, events.Start, events.Restart:
containerCouldBeLogging = true
case events.Exited:
containerCouldBeLogging = false
if doTail {
doTailFunc()
}
return
}
continue
}

View file

@ -76,6 +76,27 @@ ${cid[0]} d" "Sequential output from logs"
_log_test_multi journald
}
function _log_test_restarted() {
run_podman run --log-driver=$1 --name logtest $IMAGE sh -c 'start=0; if test -s log; then start=`tail -n 1 log`; fi; seq `expr $start + 1` `expr $start + 10` | tee -a log'
run_podman start -a logtest
logfile=$(mktemp -p ${PODMAN_TMPDIR} logfileXXXXXXXX)
$PODMAN $_PODMAN_TEST_OPTS logs -f logtest > $logfile
expected=$(mktemp -p ${PODMAN_TMPDIR} expectedXXXXXXXX)
seq 1 20 > $expected
diff -u ${expected} ${logfile}
}
@test "podman logs restarted - k8s-file" {
_log_test_restarted k8s-file
}
@test "podman logs restarted journald" {
# We can't use journald on RHEL as rootless: rhbz#1895105
skip_if_journald_unavailable
_log_test_restarted journald
}
@test "podman logs - journald log driver requires journald events backend" {
skip_if_remote "remote does not support --events-backend"
# We can't use journald on RHEL as rootless: rhbz#1895105