Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: AddMatch conflict with SeekTail? #315

Open
baude opened this issue Aug 2, 2019 · 2 comments
Open

Question: AddMatch conflict with SeekTail? #315

baude opened this issue Aug 2, 2019 · 2 comments

Comments

@baude
Copy link

baude commented Aug 2, 2019

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

}
@rhatdan
Copy link
Contributor

rhatdan commented Aug 2, 2019

@jonboulle PTAL

@lucab
Copy link
Contributor

lucab commented Aug 6, 2019

We were having an out-of-band chat about this.
I don't have any reference at hand, but I seem to remember this is in fact a corner-case of the interaction between seeking and filtering.
There isn't much logic related to that in this wrapping library, so I think it's a behavior directly coming from the libsystemd C library.
This is just my gut feeling though, it would need to confirmed by reading through the C side. I'm not venturing on that journey right now due time shortage, thus keeping this ticket open until somebody reports back with relevant references. At that point, we can either fix the corner-case or improve the documentation to mention those non-orthogonal actions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants