mirror of
https://github.com/nikoksr/notify.git
synced 2025-01-10 00:28:36 +02:00
74 lines
2.4 KiB
Go
74 lines
2.4 KiB
Go
|
package syslog
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"io"
|
||
|
"log/syslog"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/pkg/errors"
|
||
|
)
|
||
|
|
||
|
// mockSyslogWriter abstracts log/syslog for writing unit tests.
|
||
|
type syslogWriter interface {
|
||
|
io.WriteCloser
|
||
|
}
|
||
|
|
||
|
// Service encapsulates a syslog daemon writer.
|
||
|
type Service struct {
|
||
|
writer syslogWriter
|
||
|
}
|
||
|
|
||
|
// dial is a wrapper function around syslog.Dial. It normalizes the prefix tag in case that it's empty and returns
|
||
|
// a new Service with the writer field set to writer from the call to syslog.Dial.
|
||
|
func dial(network, raddr string, priority syslog.Priority, tag string) (*Service, error) {
|
||
|
if strings.TrimSpace(tag) == "" {
|
||
|
tag = "notify"
|
||
|
}
|
||
|
|
||
|
// Usually we could call syslog.New and syslog.Dial respectively for specific use-cases. But since syslog.New is
|
||
|
// only a wrapper around a call to syslog.Dial without information about the network we're doing the same here to
|
||
|
// keep the API a little more clean.
|
||
|
writer, err := syslog.Dial(network, raddr, priority, tag)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return &Service{writer: writer}, nil
|
||
|
}
|
||
|
|
||
|
// New returns a new instance of a Service notification service. Parameter 'tag' is used as a log prefix and may be left
|
||
|
// empty, it has a fallback value.
|
||
|
func New(priority syslog.Priority, tag string) (*Service, error) {
|
||
|
return dial("", "", priority, tag)
|
||
|
}
|
||
|
|
||
|
// NewFromDial returns a new instance of a Service notification service. The underlying syslog writer establishes a
|
||
|
// connection to a log daemon by connecting to address raddr on the specified network. Parameter 'tag' is used as a log
|
||
|
// prefix and may be left empty, it has a fallback value.
|
||
|
// Calling NewFromDial with network and raddr being empty strings is equal in function to calling New directly.
|
||
|
func NewFromDial(network, raddr string, priority syslog.Priority, tag string) (*Service, error) {
|
||
|
return dial(network, raddr, priority, tag)
|
||
|
}
|
||
|
|
||
|
// Close the underlying syslog writer.
|
||
|
func (s *Service) Close() error {
|
||
|
return s.writer.Close()
|
||
|
}
|
||
|
|
||
|
// Send takes a message subject and a message body and sends them to all previously set channels.
|
||
|
// user used for sending the message has to be a member of the channel.
|
||
|
func (s *Service) Send(ctx context.Context, subject, message string) error {
|
||
|
select {
|
||
|
case <-ctx.Done():
|
||
|
return ctx.Err()
|
||
|
default:
|
||
|
_, err := s.writer.Write([]byte(subject + ": " + message))
|
||
|
if err != nil {
|
||
|
return errors.Wrap(err, "failed to write message to syslog")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|