srslog.go 4.3 KB

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