mirror of
https://gitlab.com/ric_harvey/MailHog.git
synced 2024-11-25 15:24:03 +00:00
222 lines
4.9 KiB
Go
222 lines
4.9 KiB
Go
|
package logger
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/ian-kent/go-log/appenders"
|
||
|
"github.com/ian-kent/go-log/layout"
|
||
|
"github.com/ian-kent/go-log/levels"
|
||
|
)
|
||
|
|
||
|
// Logger represents a logger
|
||
|
type Logger interface {
|
||
|
Level() levels.LogLevel
|
||
|
Name() string
|
||
|
FullName() string
|
||
|
Enabled() map[levels.LogLevel]bool
|
||
|
Appender() Appender
|
||
|
Children() []Logger
|
||
|
Parent() Logger
|
||
|
GetLogger(string) Logger
|
||
|
SetLevel(levels.LogLevel)
|
||
|
Log(levels.LogLevel, ...interface{})
|
||
|
SetAppender(appender Appender)
|
||
|
|
||
|
Debug(params ...interface{})
|
||
|
Info(params ...interface{})
|
||
|
Warn(params ...interface{})
|
||
|
Error(params ...interface{})
|
||
|
Trace(params ...interface{})
|
||
|
Printf(params ...interface{})
|
||
|
Println(params ...interface{})
|
||
|
Fatal(params ...interface{})
|
||
|
Fatalf(params ...interface{})
|
||
|
}
|
||
|
|
||
|
type logger struct {
|
||
|
level levels.LogLevel
|
||
|
name string
|
||
|
enabled map[levels.LogLevel]bool
|
||
|
appender Appender
|
||
|
children []Logger
|
||
|
parent Logger
|
||
|
ExitOnFatal bool
|
||
|
}
|
||
|
|
||
|
// Appender represents a log appender
|
||
|
type Appender interface {
|
||
|
Write(level levels.LogLevel, message string, args ...interface{})
|
||
|
SetLayout(layout layout.Layout)
|
||
|
Layout() layout.Layout
|
||
|
}
|
||
|
|
||
|
// New returns a new Logger
|
||
|
func New(name string) Logger {
|
||
|
l := Logger(&logger{
|
||
|
level: levels.DEBUG,
|
||
|
name: name,
|
||
|
enabled: make(map[levels.LogLevel]bool),
|
||
|
appender: appenders.Console(),
|
||
|
children: make([]Logger, 0),
|
||
|
parent: nil,
|
||
|
ExitOnFatal: true,
|
||
|
})
|
||
|
l.SetLevel(levels.DEBUG)
|
||
|
return l
|
||
|
}
|
||
|
|
||
|
func unwrap(args ...interface{}) []interface{} {
|
||
|
head := args[0]
|
||
|
switch head.(type) {
|
||
|
case func() (string, []interface{}):
|
||
|
msg, args := head.(func() (string, []interface{}))()
|
||
|
args = unwrap(args...)
|
||
|
return append([]interface{}{msg}, args...)
|
||
|
case func() []interface{}:
|
||
|
args = unwrap(head.(func() []interface{})()...)
|
||
|
case func(...interface{}) []interface{}:
|
||
|
args = unwrap(head.(func(...interface{}) []interface{})(args[1:]...)...)
|
||
|
}
|
||
|
return args
|
||
|
}
|
||
|
|
||
|
func (l *logger) New(name string) Logger {
|
||
|
lg := Logger(&logger{
|
||
|
level: levels.INHERIT,
|
||
|
name: name,
|
||
|
enabled: make(map[levels.LogLevel]bool),
|
||
|
appender: nil,
|
||
|
children: make([]Logger, 0),
|
||
|
parent: l,
|
||
|
})
|
||
|
l.children = append(l.children, lg)
|
||
|
return lg
|
||
|
}
|
||
|
|
||
|
func (l *logger) GetLogger(name string) Logger {
|
||
|
bits := strings.Split(name, ".")
|
||
|
|
||
|
if l.name == bits[0] {
|
||
|
if len(bits) == 1 {
|
||
|
return l
|
||
|
}
|
||
|
|
||
|
child := bits[1]
|
||
|
n := strings.Join(bits[1:], ".")
|
||
|
for _, c := range l.children {
|
||
|
if c.Name() == child {
|
||
|
return c.GetLogger(n)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
lg := l.New(child)
|
||
|
return lg.GetLogger(n)
|
||
|
}
|
||
|
lg := l.New(bits[0])
|
||
|
return lg.GetLogger(name)
|
||
|
}
|
||
|
|
||
|
type stringer interface {
|
||
|
String() string
|
||
|
}
|
||
|
|
||
|
func (l *logger) write(level levels.LogLevel, params ...interface{}) {
|
||
|
a := l.Appender()
|
||
|
if a != nil {
|
||
|
if s, ok := params[0].(string); ok {
|
||
|
a.Write(level, s, params[1:]...)
|
||
|
} else if s, ok := params[0].(stringer); ok {
|
||
|
a.Write(level, s.String(), params[1:]...)
|
||
|
} else {
|
||
|
a.Write(level, fmt.Sprintf("%s", params[0]), params[1:]...)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (l *logger) Appender() Appender {
|
||
|
if a := l.appender; a != nil {
|
||
|
return a
|
||
|
}
|
||
|
if l.parent != nil {
|
||
|
if a := l.parent.Appender(); a != nil {
|
||
|
return a
|
||
|
}
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (l *logger) Log(level levels.LogLevel, params ...interface{}) {
|
||
|
if !l.Enabled()[level] {
|
||
|
return
|
||
|
}
|
||
|
l.write(level, unwrap(params...)...)
|
||
|
|
||
|
if l.ExitOnFatal && level == levels.FATAL {
|
||
|
os.Exit(1)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (l *logger) Level() levels.LogLevel {
|
||
|
if l.level == levels.INHERIT {
|
||
|
return l.parent.Level()
|
||
|
}
|
||
|
return l.level
|
||
|
}
|
||
|
|
||
|
func (l *logger) Enabled() map[levels.LogLevel]bool {
|
||
|
if l.level == levels.INHERIT {
|
||
|
return l.parent.Enabled()
|
||
|
}
|
||
|
return l.enabled
|
||
|
}
|
||
|
|
||
|
func (l *logger) Name() string {
|
||
|
return l.name
|
||
|
}
|
||
|
|
||
|
func (l *logger) FullName() string {
|
||
|
n := l.name
|
||
|
if l.parent != nil {
|
||
|
p := l.parent.FullName()
|
||
|
if len(p) > 0 {
|
||
|
n = l.parent.FullName() + "." + n
|
||
|
}
|
||
|
}
|
||
|
return n
|
||
|
}
|
||
|
|
||
|
func (l *logger) Children() []Logger {
|
||
|
return l.children
|
||
|
}
|
||
|
|
||
|
func (l *logger) Parent() Logger {
|
||
|
return l.parent
|
||
|
}
|
||
|
|
||
|
func (l *logger) SetLevel(level levels.LogLevel) {
|
||
|
l.level = level
|
||
|
for k := range levels.LogLevelsToString {
|
||
|
if k <= level {
|
||
|
l.enabled[k] = true
|
||
|
} else {
|
||
|
l.enabled[k] = false
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (l *logger) SetAppender(appender Appender) {
|
||
|
l.appender = appender
|
||
|
}
|
||
|
|
||
|
func (l *logger) Debug(params ...interface{}) { l.Log(levels.DEBUG, params...) }
|
||
|
func (l *logger) Info(params ...interface{}) { l.Log(levels.INFO, params...) }
|
||
|
func (l *logger) Warn(params ...interface{}) { l.Log(levels.WARN, params...) }
|
||
|
func (l *logger) Error(params ...interface{}) { l.Log(levels.ERROR, params...) }
|
||
|
func (l *logger) Trace(params ...interface{}) { l.Log(levels.TRACE, params...) }
|
||
|
func (l *logger) Printf(params ...interface{}) { l.Log(levels.INFO, params...) }
|
||
|
func (l *logger) Println(params ...interface{}) { l.Log(levels.INFO, params...) }
|
||
|
func (l *logger) Fatal(params ...interface{}) { l.Log(levels.FATAL, params...) }
|
||
|
func (l *logger) Fatalf(params ...interface{}) { l.Log(levels.FATAL, params...) }
|