Skip to content

Question: AddMatch conflict with SeekTail? #315

Open
@baude

Description

@baude

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

}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions