journal/conn.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
}