Open
Description
Not sure where else to direct this question. in the libpod/podman (github.com/containers/libpod), we implement an event system that reads and writes to journald. On the read, by default we want be able to seek the tail of the journal and "watch" for events from there. The following code does in fact do that with one annoying problem. If I enable (uncomment) the AddMatch to filter more specifically to our events, I am getting "old" events being processed; that is to say, events that occurred in the past.
Could someone take a quick look here and advise?
// Read reads events from the journal and sends qualified events to the event channel
func (e EventJournalD) Read(options ReadOptions) error {
eventOptions, err := generateEventOptions(options.Filters, options.Since, options.Until)
if err != nil {
return errors.Wrapf(err, "failed to generate event options")
}
//podmanJournal := sdjournal.Match{Field: "SYSLOG_IDENTIFIER", Value: "podman"} //nolint
j, err := sdjournal.NewJournal() //nolint
if err != nil {
return err
}
if len(options.Since) == 0 && len(options.Until) == 0 && options.Stream {
fmt.Println("--->")
if err := j.SeekTail(); err != nil {
return errors.Wrap(err, "failed to seek end of journal")
}
}
// the api requires a next|prev before getting a cursor
if _, err := j.Next(); err != nil {
return err
}
prevCursor, err := j.GetCursor()
if err != nil {
return err
}
//if err := j.AddMatch(podmanJournal.String()); err != nil {
// return errors.Wrap(err, "failed to add filter for event log")
//}
defer close(options.EventChannel)
for {
if _, err := j.Next(); err != nil {
return err
}
newCursor, err := j.GetCursor()
if err != nil {
return err
}
if prevCursor == newCursor {
if len(options.Until) > 0 || !options.Stream {
break
}
_ = j.Wait(sdjournal.IndefiniteWait) //nolint
continue
}
prevCursor = newCursor
entry, err := j.GetEntry()
if err != nil {
return err
}
newEvent, err := newEventFromJournalEntry(entry)
if err != nil {
// We can't decode this event.
// Don't fail hard - that would make events unusable.
// Instead, log and continue.
if errors.Cause(err) != ErrEventTypeBlank {
logrus.Errorf("Unable to decode event: %v", err)
}
continue
}
include := true
for _, filter := range eventOptions {
include = include && filter(newEvent)
}
if include {
options.EventChannel <- newEvent
}
}
return nil
}