func (r *Reader) Read(b []byte) (int, error) {
	if r.msgReader == nil {
		if r.UseLimit && r.Limit == 0 {
			return 0, io.EOF
		}
		var (
			c        uint64
			err      error
			skipRead bool
		)
		if r.n == 0 {
			if cursor, err := r.Journal.GetCursor(); err == nil {
				if cursor != r.Cursor {
					skipRead = true
				}
			}
		}
		if !skipRead {
			if r.ReadReverse {
				c, err = r.Journal.Previous()
			} else {
				c, err = r.Journal.Next()
			}
			if err != nil {
				return 0, err
			}
			if c == 0 {
				if r.contentFormatter.GetContentType() == ContentTypeEventStream {
					if time.Since(r.eofTime) < time.Duration(time.Second*15) {
						return 0, io.EOF
					}
					r.msgReader = bytes.NewReader([]byte(": ping\n\n"))
					r.eofTime = time.Now()
					goto reader
				}
				return 0, io.EOF
			}
		}
		r.eofTime = time.Now()
		if r.contentFormatter == nil {
			return 0, ErrUninitializedReader
		}
		entry, err := r.Journal.GetEntry()
		if err != nil {
			return 0, err
		}
		entryBytes, err := r.contentFormatter.FormatEntry(entry)
		if err != nil {
			return 0, err
		}
		r.msgReader = bytes.NewReader(entryBytes)
		if r.UseLimit && r.Limit > 0 {
			r.Limit--
		}
		r.n++
	}
reader:
	var sz int
	sz, err := r.msgReader.Read(b)
	if err == io.EOF {
		r.msgReader = nil
		return sz, nil
	}
	if err != nil {
		return sz, err
	}
	if r.msgReader.Len() == 0 {
		r.msgReader = nil
	}
	return sz, nil
}
Read is implementation of Reader interface.
Most of the code was taken from https://github.com/coreos/go-systemd/blob/master/sdjournal/read.go
package reader
import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"time"
	"github.com/coreos/go-systemd/sdjournal"
	"github.com/sirupsen/logrus"
)
var ErrUninitializedReader = errors.New("NewReader() must be called before using journal reader")
func NewReader(contentFormatter EntryFormatter, options ...Option) (r *Reader, err error) {
	if contentFormatter == nil {
		contentFormatter = FormatText{}
	}
	r = &Reader{
		contentFormatter: contentFormatter,
	}
	r.Journal, err = sdjournal.NewJournal()
	if err != nil {
		return r, err
	}
	for _, opt := range options {
		if opt != nil {
			if err := opt(r); err != nil {
				return r, err
			}
		}
	}
	return r, nil
}
type Reader struct {
	Journal                  *sdjournal.Journal
	Cursor                   string
	Limit                    uint64
	UseLimit                 bool
	SkippedNext, SkippedPrev uint64
	ReadReverse              bool
	eofTime          time.Time
	msgReader        *bytes.Reader
	contentFormatter EntryFormatter
	n uint64
	matchFns []func(journal *sdjournal.Journal)
}
func (r *Reader) SkipNext(n uint64) error {
	var err error
	r.SkippedNext, err = r.Journal.NextSkip(n)
	return err
}
func (r *Reader) SkipPrev(n uint64) error {
	if r.Cursor == "" {
		if err := r.Journal.SeekTail(); err != nil {
			return fmt.Errorf("Could not move to the end if the journal: %s", err)
		}
	}
	var err error
	r.SkippedPrev, err = r.Journal.PreviousSkip(n)
	return err
}
func (r *Reader) SeekCursor(c string) error {
	if err := r.Journal.SeekCursor(c); err != nil {
		return err
	}
	if _, err := r.Journal.Next(); err != nil {
		return err
	}
	if err := r.Journal.TestCursor(c); err != nil {
		return fmt.Errorf("Cursor %s not found: %s", c, err)
	}
	return nil
}