xesite/vendor/github.com/Xe/ln/logger.go

142 lines
2.6 KiB
Go

package ln
import (
"fmt"
"os"
"time"
"github.com/pkg/errors"
)
// Logger holds the current priority and list of filters
type Logger struct {
Filters []Filter
}
// DefaultLogger is the default implementation of Logger
var DefaultLogger *Logger
func init() {
var defaultFilters []Filter
// Default to STDOUT for logging, but allow LN_OUT to change it.
out := os.Stdout
if os.Getenv("LN_OUT") == "<stderr>" {
out = os.Stderr
}
defaultFilters = append(defaultFilters, NewWriterFilter(out, nil))
DefaultLogger = &Logger{
Filters: defaultFilters,
}
}
// F is a key-value mapping for structured data.
type F map[string]interface{}
type Fer interface {
F() map[string]interface{}
}
// Event represents an event
type Event struct {
Time time.Time
Data F
Message string
}
// Log is the generic logging method.
func (l *Logger) Log(xs ...interface{}) {
var bits []interface{}
event := Event{Time: time.Now()}
addF := func(bf F) {
if event.Data == nil {
event.Data = bf
} else {
for k, v := range bf {
event.Data[k] = v
}
}
}
// Assemble the event
for _, b := range xs {
if bf, ok := b.(F); ok {
addF(bf)
} else if fer, ok := b.(Fer); ok {
addF(F(fer.F()))
} else {
bits = append(bits, b)
}
}
event.Message = fmt.Sprint(bits...)
if os.Getenv("LN_DEBUG_ALL_EVENTS") == "1" {
frame := callersFrame()
if event.Data == nil {
event.Data = make(F)
}
event.Data["_lineno"] = frame.lineno
event.Data["_function"] = frame.function
event.Data["_filename"] = frame.filename
}
l.filter(event)
}
func (l *Logger) filter(e Event) {
for _, f := range l.Filters {
if !f.Apply(e) {
return
}
}
}
// Error logs an error and information about the context of said error.
func (l *Logger) Error(err error, xs ...interface{}) {
data := F{}
frame := callersFrame()
data["_lineno"] = frame.lineno
data["_function"] = frame.function
data["_filename"] = frame.filename
data["err"] = err
cause := errors.Cause(err)
if cause != nil {
data["cause"] = cause.Error()
}
xs = append(xs, data)
l.Log(xs...)
}
// Fatal logs this set of values, then exits with status code 1.
func (l *Logger) Fatal(xs ...interface{}) {
l.Log(xs...)
os.Exit(1)
}
// Default Implementation
// Log is the generic logging method.
func Log(xs ...interface{}) {
DefaultLogger.Log(xs...)
}
// Error logs an error and information about the context of said error.
func Error(err error, xs ...interface{}) {
DefaultLogger.Error(err, xs...)
}
// Fatal logs this set of values, then exits with status code 1.
func Fatal(xs ...interface{}) {
DefaultLogger.Fatal(xs...)
}