79 lines
1.3 KiB
Go
79 lines
1.3 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"sync"
|
||
|
"time"
|
||
|
|
||
|
"github.com/coreos/go-systemd/sdjournal"
|
||
|
)
|
||
|
|
||
|
// Journal represents a lockable systemd journal.
|
||
|
type Journal struct {
|
||
|
*sdjournal.Journal
|
||
|
sync.Mutex
|
||
|
Path string
|
||
|
}
|
||
|
|
||
|
// NewJournal returns a Journal for reading journal entries.
|
||
|
func NewJournal(unit, slice, path string) (j *Journal, err error) {
|
||
|
j = new(Journal)
|
||
|
if path != "" {
|
||
|
j.Journal, err = sdjournal.NewJournalFromDir(path)
|
||
|
j.Path = path
|
||
|
} else {
|
||
|
j.Journal, err = sdjournal.NewJournal()
|
||
|
j.Path = "journald"
|
||
|
}
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if slice != "" {
|
||
|
err = j.AddMatch("_SYSTEMD_SLICE=" + slice)
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
} else if unit != "" {
|
||
|
err = j.AddMatch("_SYSTEMD_UNIT=" + unit)
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// NextMessage reads the next message from the journal.
|
||
|
func (j *Journal) NextMessage() (s string, c uint64, err error) {
|
||
|
var e *sdjournal.JournalEntry
|
||
|
|
||
|
// Read to next
|
||
|
c, err = j.Next()
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
// Return when on the end of journal
|
||
|
if c == 0 {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// Get entry
|
||
|
e, err = j.GetEntry()
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
ts := time.Unix(0, int64(e.RealtimeTimestamp)*int64(time.Microsecond))
|
||
|
|
||
|
// Format entry
|
||
|
s = fmt.Sprintf(
|
||
|
"%s %s %s[%s]: %s",
|
||
|
ts.Format(time.Stamp),
|
||
|
e.Fields["_HOSTNAME"],
|
||
|
e.Fields["SYSLOG_IDENTIFIER"],
|
||
|
e.Fields["_PID"],
|
||
|
e.Fields["MESSAGE"],
|
||
|
)
|
||
|
|
||
|
return
|
||
|
}
|