1package srslog 2 3import ( 4 "crypto/tls" 5 "crypto/x509" 6 "errors" 7 "io/ioutil" 8 "log" 9 "net" 10 "os" 11) 12 13// This interface allows us to work with both local and network connections, 14// and enables Solaris support (see syslog_unix.go). 15type serverConn interface { 16 writeString(framer Framer, formatter Formatter, p Priority, hostname, tag, s string) error 17 close() error 18} 19 20// DialFunc is the function signature to be used for a custom dialer callback 21// with DialWithCustomDialer 22type DialFunc func(string, string) (net.Conn, error) 23 24// New establishes a new connection to the system log daemon. Each 25// write to the returned Writer sends a log message with the given 26// priority and prefix. 27func New(priority Priority, tag string) (w *Writer, err error) { 28 return Dial("", "", priority, tag) 29} 30 31// Dial establishes a connection to a log daemon by connecting to 32// address raddr on the specified network. Each write to the returned 33// Writer sends a log message with the given facility, severity and 34// tag. 35// If network is empty, Dial will connect to the local syslog server. 36func Dial(network, raddr string, priority Priority, tag string) (*Writer, error) { 37 return DialWithTLSConfig(network, raddr, priority, tag, nil) 38} 39 40// ErrNilDialFunc is returned from DialWithCustomDialer when a nil DialFunc is passed, 41// avoiding a nil pointer deference panic. 42var ErrNilDialFunc = errors.New("srslog: nil DialFunc passed to DialWithCustomDialer") 43 44// DialWithCustomDialer establishes a connection by calling customDial. 45// Each write to the returned Writer sends a log message with the given facility, severity and tag. 46// Network must be "custom" in order for this package to use customDial. 47// While network and raddr will be passed to customDial, it is allowed for customDial to ignore them. 48// If customDial is nil, this function returns ErrNilDialFunc. 49func DialWithCustomDialer(network, raddr string, priority Priority, tag string, customDial DialFunc) (*Writer, error) { 50 if customDial == nil { 51 return nil, ErrNilDialFunc 52 } 53 return dialAllParameters(network, raddr, priority, tag, nil, customDial) 54} 55 56// DialWithTLSCertPath establishes a secure connection to a log daemon by connecting to 57// address raddr on the specified network. It uses certPath to load TLS certificates and configure 58// the secure connection. 59func DialWithTLSCertPath(network, raddr string, priority Priority, tag, certPath string) (*Writer, error) { 60 serverCert, err := ioutil.ReadFile(certPath) 61 if err != nil { 62 return nil, err 63 } 64 65 return DialWithTLSCert(network, raddr, priority, tag, serverCert) 66} 67 68// DialWIthTLSCert establishes a secure connection to a log daemon by connecting to 69// address raddr on the specified network. It uses serverCert to load a TLS certificate 70// and configure the secure connection. 71func DialWithTLSCert(network, raddr string, priority Priority, tag string, serverCert []byte) (*Writer, error) { 72 pool := x509.NewCertPool() 73 pool.AppendCertsFromPEM(serverCert) 74 config := tls.Config{ 75 RootCAs: pool, 76 } 77 78 return DialWithTLSConfig(network, raddr, priority, tag, &config) 79} 80 81// DialWithTLSConfig establishes a secure connection to a log daemon by connecting to 82// address raddr on the specified network. It uses tlsConfig to configure the secure connection. 83func DialWithTLSConfig(network, raddr string, priority Priority, tag string, tlsConfig *tls.Config) (*Writer, error) { 84 return dialAllParameters(network, raddr, priority, tag, tlsConfig, nil) 85} 86 87// implementation of the various functions above 88func dialAllParameters(network, raddr string, priority Priority, tag string, tlsConfig *tls.Config, customDial DialFunc) (*Writer, error) { 89 if err := validatePriority(priority); err != nil { 90 return nil, err 91 } 92 93 if tag == "" { 94 tag = os.Args[0] 95 } 96 hostname, _ := os.Hostname() 97 98 w := &Writer{ 99 priority: priority, 100 tag: tag, 101 hostname: hostname, 102 network: network, 103 raddr: raddr, 104 tlsConfig: tlsConfig, 105 customDial: customDial, 106 } 107 108 _, err := w.connect() 109 if err != nil { 110 return nil, err 111 } 112 return w, err 113} 114 115// NewLogger creates a log.Logger whose output is written to 116// the system log service with the specified priority. The logFlag 117// argument is the flag set passed through to log.New to create 118// the Logger. 119func NewLogger(p Priority, logFlag int) (*log.Logger, error) { 120 s, err := New(p, "") 121 if err != nil { 122 return nil, err 123 } 124 return log.New(s, "", logFlag), nil 125} 126