...

Source file src/github.com/go-kit/log/syslog/syslog.go

Documentation: github.com/go-kit/log/syslog

     1  //go:build !windows && !plan9 && !nacl
     2  // +build !windows,!plan9,!nacl
     3  
     4  // Package syslog provides a Logger that writes to syslog.
     5  package syslog
     6  
     7  import (
     8  	"bytes"
     9  	"io"
    10  	"sync"
    11  
    12  	gosyslog "log/syslog"
    13  
    14  	"github.com/go-kit/log"
    15  	"github.com/go-kit/log/level"
    16  )
    17  
    18  // SyslogWriter is an interface wrapping stdlib syslog Writer.
    19  type SyslogWriter interface {
    20  	Write([]byte) (int, error)
    21  	Close() error
    22  	Emerg(string) error
    23  	Alert(string) error
    24  	Crit(string) error
    25  	Err(string) error
    26  	Warning(string) error
    27  	Notice(string) error
    28  	Info(string) error
    29  	Debug(string) error
    30  }
    31  
    32  // NewSyslogLogger returns a new Logger which writes to syslog in syslog format.
    33  // The body of the log message is the formatted output from the Logger returned
    34  // by newLogger.
    35  func NewSyslogLogger(w SyslogWriter, newLogger func(io.Writer) log.Logger, options ...Option) log.Logger {
    36  	l := &syslogLogger{
    37  		w:                w,
    38  		newLogger:        newLogger,
    39  		prioritySelector: defaultPrioritySelector,
    40  		bufPool: sync.Pool{New: func() interface{} {
    41  			return &loggerBuf{}
    42  		}},
    43  	}
    44  
    45  	for _, option := range options {
    46  		option(l)
    47  	}
    48  
    49  	return l
    50  }
    51  
    52  type syslogLogger struct {
    53  	w                SyslogWriter
    54  	newLogger        func(io.Writer) log.Logger
    55  	prioritySelector PrioritySelector
    56  	bufPool          sync.Pool
    57  }
    58  
    59  func (l *syslogLogger) Log(keyvals ...interface{}) error {
    60  	level := l.prioritySelector(keyvals...)
    61  
    62  	lb := l.getLoggerBuf()
    63  	defer l.putLoggerBuf(lb)
    64  	if err := lb.logger.Log(keyvals...); err != nil {
    65  		return err
    66  	}
    67  
    68  	switch level {
    69  	case gosyslog.LOG_EMERG:
    70  		return l.w.Emerg(lb.buf.String())
    71  	case gosyslog.LOG_ALERT:
    72  		return l.w.Alert(lb.buf.String())
    73  	case gosyslog.LOG_CRIT:
    74  		return l.w.Crit(lb.buf.String())
    75  	case gosyslog.LOG_ERR:
    76  		return l.w.Err(lb.buf.String())
    77  	case gosyslog.LOG_WARNING:
    78  		return l.w.Warning(lb.buf.String())
    79  	case gosyslog.LOG_NOTICE:
    80  		return l.w.Notice(lb.buf.String())
    81  	case gosyslog.LOG_INFO:
    82  		return l.w.Info(lb.buf.String())
    83  	case gosyslog.LOG_DEBUG:
    84  		return l.w.Debug(lb.buf.String())
    85  	default:
    86  		_, err := l.w.Write(lb.buf.Bytes())
    87  		return err
    88  	}
    89  }
    90  
    91  type loggerBuf struct {
    92  	buf    *bytes.Buffer
    93  	logger log.Logger
    94  }
    95  
    96  func (l *syslogLogger) getLoggerBuf() *loggerBuf {
    97  	lb := l.bufPool.Get().(*loggerBuf)
    98  	if lb.buf == nil {
    99  		lb.buf = &bytes.Buffer{}
   100  		lb.logger = l.newLogger(lb.buf)
   101  	} else {
   102  		lb.buf.Reset()
   103  	}
   104  	return lb
   105  }
   106  
   107  func (l *syslogLogger) putLoggerBuf(lb *loggerBuf) {
   108  	l.bufPool.Put(lb)
   109  }
   110  
   111  // Option sets a parameter for syslog loggers.
   112  type Option func(*syslogLogger)
   113  
   114  // PrioritySelector inspects the list of keyvals and selects a syslog priority.
   115  type PrioritySelector func(keyvals ...interface{}) gosyslog.Priority
   116  
   117  // PrioritySelectorOption sets priority selector function to choose syslog
   118  // priority.
   119  func PrioritySelectorOption(selector PrioritySelector) Option {
   120  	return func(l *syslogLogger) { l.prioritySelector = selector }
   121  }
   122  
   123  func defaultPrioritySelector(keyvals ...interface{}) gosyslog.Priority {
   124  	l := len(keyvals)
   125  	for i := 0; i < l; i += 2 {
   126  		if keyvals[i] == level.Key() {
   127  			var val interface{}
   128  			if i+1 < l {
   129  				val = keyvals[i+1]
   130  			}
   131  			if v, ok := val.(level.Value); ok {
   132  				switch v {
   133  				case level.DebugValue():
   134  					return gosyslog.LOG_DEBUG
   135  				case level.InfoValue():
   136  					return gosyslog.LOG_INFO
   137  				case level.WarnValue():
   138  					return gosyslog.LOG_WARNING
   139  				case level.ErrorValue():
   140  					return gosyslog.LOG_ERR
   141  				}
   142  			}
   143  		}
   144  	}
   145  
   146  	return gosyslog.LOG_INFO
   147  }
   148  

View as plain text