@@ -44,19 +44,32 @@ type JournalReaderConfig struct {
4444 // If not empty, the journal instance will point to a journal residing
4545 // in this directory. The supplied path may be relative or absolute.
4646 Path string
47+
48+ // If not nil, Formatter will be used to translate the resulting entries
49+ // into strings. If not set, the default format (timestamp and message field)
50+ // will be used. If Formatter returns an error, Read will stop and return the error.
51+ Formatter func (entry * JournalEntry ) (string , error )
4752}
4853
4954// JournalReader is an io.ReadCloser which provides a simple interface for iterating through the
5055// systemd journal. A JournalReader is not safe for concurrent use by multiple goroutines.
5156type JournalReader struct {
5257 journal * Journal
5358 msgReader * strings.Reader
59+ formatter func (entry * JournalEntry ) (string , error )
5460}
5561
5662// NewJournalReader creates a new JournalReader with configuration options that are similar to the
5763// systemd journalctl tool's iteration and filtering features.
5864func NewJournalReader (config JournalReaderConfig ) (* JournalReader , error ) {
59- r := & JournalReader {}
65+ // use simpelMessageFormatter as default formatter.
66+ if config .Formatter == nil {
67+ config .Formatter = simpelMessageFormatter
68+ }
69+
70+ r := & JournalReader {
71+ formatter : config .Formatter ,
72+ }
6073
6174 // Open the journal
6275 var err error
@@ -137,9 +150,14 @@ func (r *JournalReader) Read(b []byte) (int, error) {
137150 return 0 , io .EOF
138151 }
139152
153+ entry , err := r .journal .GetEntry ()
154+ if err != nil {
155+ return 0 , err
156+ }
157+
140158 // Build a message
141159 var msg string
142- msg , err = r .buildMessage ( )
160+ msg , err = r .formatter ( entry )
143161
144162 if err != nil {
145163 return 0 , err
@@ -238,20 +256,16 @@ process:
238256 return
239257}
240258
241- // buildMessage returns a string representing the current journal entry in a simple format which
259+ // simpelMessageFormatter is the default formatter.
260+ // It returns a string representing the current journal entry in a simple format which
242261// includes the entry timestamp and MESSAGE field.
243- func (r * JournalReader ) buildMessage () (string , error ) {
244- var msg string
245- var usec uint64
246- var err error
247-
248- if msg , err = r .journal .GetData ("MESSAGE" ); err != nil {
249- return "" , err
250- }
262+ func simpelMessageFormatter (entry * JournalEntry ) (string , error ) {
263+ msg , ok := entry .Fields ["MESSAGE" ]
251264
252- if usec , err = r . journal . GetRealtimeUsec (); err != nil {
253- return "" , err
265+ if ! ok {
266+ return "" , fmt . Errorf ( "no MESSAGE field present in journal entry" )
254267 }
268+ usec := entry .RealtimeTimestamp
255269
256270 timestamp := time .Unix (0 , int64 (usec )* int64 (time .Microsecond ))
257271
0 commit comments