92 lines
2.1 KiB
Go
92 lines
2.1 KiB
Go
|
package journal
|
||
|
|
||
|
import (
|
||
|
"net"
|
||
|
"sync"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
// WellKnownSocketPath is where we generally expect to find the systemd
|
||
|
// journal daemon's socket.
|
||
|
WellKnownSocketPath = "/run/systemd/journal/socket"
|
||
|
)
|
||
|
|
||
|
// Conn represents an active, open connection to the systemd journal that is
|
||
|
// ready to write log entries.
|
||
|
type Conn struct {
|
||
|
// Common attributes which are emitted for all messages.
|
||
|
Common []Attr
|
||
|
|
||
|
// ErrHandler is called if there is an error writing to the log. If nil,
|
||
|
// the error is silently discarded.
|
||
|
ErrHandler func(error)
|
||
|
|
||
|
s *net.UnixConn
|
||
|
bufs sync.Pool
|
||
|
}
|
||
|
|
||
|
// Connect to the systemd journal. If the path string is empty, then it uses the
|
||
|
// well-known socket path.
|
||
|
func Connect(path string) (*Conn, error) {
|
||
|
if path == "" {
|
||
|
path = WellKnownSocketPath
|
||
|
}
|
||
|
|
||
|
s, err := net.DialUnix("unixgram", nil, &net.UnixAddr{
|
||
|
Name: path,
|
||
|
Net: "unixgram",
|
||
|
})
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return &Conn{
|
||
|
s: s,
|
||
|
bufs: sync.Pool{
|
||
|
New: func() any {
|
||
|
return &net.Buffers{}
|
||
|
},
|
||
|
},
|
||
|
}, nil
|
||
|
}
|
||
|
|
||
|
var messageAttrKey = AttrKey{key: "MESSAGE"}
|
||
|
|
||
|
// Entry emits a log entry. It will add PRIORITY and MESSAGE key/value pairs
|
||
|
// as well as any Common attributes.
|
||
|
//
|
||
|
// Note: to avoid allocation / garbage, ensure attrs has capacity for an extra
|
||
|
// 2+len(c.Common) values.
|
||
|
func (c *Conn) Entry(pri Priority, msg string, attrs []Attr) {
|
||
|
err := c.EntryErr(pri, msg, attrs)
|
||
|
switch {
|
||
|
case err == nil:
|
||
|
return
|
||
|
case c.ErrHandler == nil:
|
||
|
return
|
||
|
default:
|
||
|
c.ErrHandler(err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// EntryErr is like Entry, but will propagate errors to the caller, rather than
|
||
|
// using the built-in error handler.
|
||
|
func (c *Conn) EntryErr(pri Priority, msg string, attrs []Attr) error {
|
||
|
attrs = append(attrs, pri.Attr(), Attr{
|
||
|
Key: messageAttrKey,
|
||
|
Value: []byte(msg),
|
||
|
})
|
||
|
attrs = append(attrs, c.Common...)
|
||
|
return c.WriteAttrs(attrs)
|
||
|
}
|
||
|
|
||
|
// WriteAttrs is a low-level method which writes a journal entry comprised of
|
||
|
// only the given set of attributes.
|
||
|
func (c *Conn) WriteAttrs(attrs []Attr) error {
|
||
|
buf := c.bufs.Get().(*net.Buffers)
|
||
|
*buf = (*buf)[:0]
|
||
|
err := WireWrite(buf, c.s, attrs)
|
||
|
c.bufs.Put(buf)
|
||
|
return err
|
||
|
}
|