157 lines
3.7 KiB
Go
157 lines
3.7 KiB
Go
package log
|
|
|
|
import (
|
|
stdlog "log"
|
|
"sort"
|
|
"time"
|
|
)
|
|
|
|
// assert interface compliance.
|
|
var _ Interface = (*Logger)(nil)
|
|
|
|
// Fielder is an interface for providing fields to custom types.
|
|
type Fielder interface {
|
|
Fields() Fields
|
|
}
|
|
|
|
// Fields represents a map of entry level data used for structured logging.
|
|
type Fields map[string]interface{}
|
|
|
|
// Fields implements Fielder.
|
|
func (f Fields) Fields() Fields {
|
|
return f
|
|
}
|
|
|
|
// Get field value by name.
|
|
func (f Fields) Get(name string) interface{} {
|
|
return f[name]
|
|
}
|
|
|
|
// Names returns field names sorted.
|
|
func (f Fields) Names() (v []string) {
|
|
for k := range f {
|
|
v = append(v, k)
|
|
}
|
|
|
|
sort.Strings(v)
|
|
return
|
|
}
|
|
|
|
// The HandlerFunc type is an adapter to allow the use of ordinary functions as
|
|
// log handlers. If f is a function with the appropriate signature,
|
|
// HandlerFunc(f) is a Handler object that calls f.
|
|
type HandlerFunc func(*Entry) error
|
|
|
|
// HandleLog calls f(e).
|
|
func (f HandlerFunc) HandleLog(e *Entry) error {
|
|
return f(e)
|
|
}
|
|
|
|
// Handler is used to handle log events, outputting them to
|
|
// stdio or sending them to remote services. See the "handlers"
|
|
// directory for implementations.
|
|
//
|
|
// It is left up to Handlers to implement thread-safety.
|
|
type Handler interface {
|
|
HandleLog(*Entry) error
|
|
}
|
|
|
|
// Logger represents a logger with configurable Level and Handler.
|
|
type Logger struct {
|
|
Handler Handler
|
|
Level Level
|
|
}
|
|
|
|
// WithFields returns a new entry with `fields` set.
|
|
func (l *Logger) WithFields(fields Fielder) *Entry {
|
|
return NewEntry(l).WithFields(fields.Fields())
|
|
}
|
|
|
|
// WithField returns a new entry with the `key` and `value` set.
|
|
//
|
|
// Note that the `key` should not have spaces in it - use camel
|
|
// case or underscores
|
|
func (l *Logger) WithField(key string, value interface{}) *Entry {
|
|
return NewEntry(l).WithField(key, value)
|
|
}
|
|
|
|
// WithDuration returns a new entry with the "duration" field set
|
|
// to the given duration in milliseconds.
|
|
func (l *Logger) WithDuration(d time.Duration) *Entry {
|
|
return NewEntry(l).WithDuration(d)
|
|
}
|
|
|
|
// WithError returns a new entry with the "error" set to `err`.
|
|
func (l *Logger) WithError(err error) *Entry {
|
|
return NewEntry(l).WithError(err)
|
|
}
|
|
|
|
// Debug level message.
|
|
func (l *Logger) Debug(msg string) {
|
|
NewEntry(l).Debug(msg)
|
|
}
|
|
|
|
// Info level message.
|
|
func (l *Logger) Info(msg string) {
|
|
NewEntry(l).Info(msg)
|
|
}
|
|
|
|
// Warn level message.
|
|
func (l *Logger) Warn(msg string) {
|
|
NewEntry(l).Warn(msg)
|
|
}
|
|
|
|
// Error level message.
|
|
func (l *Logger) Error(msg string) {
|
|
NewEntry(l).Error(msg)
|
|
}
|
|
|
|
// Fatal level message, followed by an exit.
|
|
func (l *Logger) Fatal(msg string) {
|
|
NewEntry(l).Fatal(msg)
|
|
}
|
|
|
|
// Debugf level formatted message.
|
|
func (l *Logger) Debugf(msg string, v ...interface{}) {
|
|
NewEntry(l).Debugf(msg, v...)
|
|
}
|
|
|
|
// Infof level formatted message.
|
|
func (l *Logger) Infof(msg string, v ...interface{}) {
|
|
NewEntry(l).Infof(msg, v...)
|
|
}
|
|
|
|
// Warnf level formatted message.
|
|
func (l *Logger) Warnf(msg string, v ...interface{}) {
|
|
NewEntry(l).Warnf(msg, v...)
|
|
}
|
|
|
|
// Errorf level formatted message.
|
|
func (l *Logger) Errorf(msg string, v ...interface{}) {
|
|
NewEntry(l).Errorf(msg, v...)
|
|
}
|
|
|
|
// Fatalf level formatted message, followed by an exit.
|
|
func (l *Logger) Fatalf(msg string, v ...interface{}) {
|
|
NewEntry(l).Fatalf(msg, v...)
|
|
}
|
|
|
|
// Trace returns a new entry with a Stop method to fire off
|
|
// a corresponding completion log, useful with defer.
|
|
func (l *Logger) Trace(msg string) *Entry {
|
|
return NewEntry(l).Trace(msg)
|
|
}
|
|
|
|
// log the message, invoking the handler. We clone the entry here
|
|
// to bypass the overhead in Entry methods when the level is not
|
|
// met.
|
|
func (l *Logger) log(level Level, e *Entry, msg string) {
|
|
if level < l.Level {
|
|
return
|
|
}
|
|
|
|
if err := l.Handler.HandleLog(e.finalize(level, msg)); err != nil {
|
|
stdlog.Printf("error logging: %s", err)
|
|
}
|
|
}
|