From c674b3dd83d1a9cb30ed235bc4302a7388e011e4 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Wed, 4 Jan 2023 17:46:50 +0100 Subject: [PATCH] journald: seek to time when --since is used Instead of reading the full journal which can be expensive we can seek based on the time. If you have a journald with many podman events just compare the time `time podman events --since 1s --stream=false` with and without this patch. Signed-off-by: Paul Holzinger --- libpod/container_log_linux.go | 11 +++++++++-- libpod/events/journal_linux.go | 9 +++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/libpod/container_log_linux.go b/libpod/container_log_linux.go index e8f957322b..ccc05d42d0 100644 --- a/libpod/container_log_linux.go +++ b/libpod/container_log_linux.go @@ -80,8 +80,15 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption return fmt.Errorf("adding filter to journald logger: %v: %w", match, err) } - if err := journal.SeekHead(); err != nil { - return err + if options.Since.IsZero() { + if err := journal.SeekHead(); err != nil { + return err + } + } else { + // seek based on time which helps to reduce unnecessary event reads + if err := journal.SeekRealtimeUsec(uint64(options.Since.UnixMicro())); err != nil { + return err + } } // API requires Next() immediately after SeekHead(). if _, err := journal.Next(); err != nil { diff --git a/libpod/events/journal_linux.go b/libpod/events/journal_linux.go index da2156c2c8..9c8b9cae11 100644 --- a/libpod/events/journal_linux.go +++ b/libpod/events/journal_linux.go @@ -121,6 +121,15 @@ func (e EventJournalD) Read(ctx context.Context, options ReadOptions) error { if _, err := j.Previous(); err != nil { return fmt.Errorf("failed to move journal cursor to previous entry: %w", err) } + } else if len(options.Since) > 0 { + since, err := util.ParseInputTime(options.Since, true) + if err != nil { + return err + } + // seek based on time which helps to reduce unnecessary event reads + if err := j.SeekRealtimeUsec(uint64(since.UnixMicro())); err != nil { + return err + } } for {