1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
|
package logger
import (
"fmt"
"github.com/revel/config"
"time"
)
// The LogHandler defines the interface to handle the log records
type (
// The Multilogger reduces the number of exposed defined logging variables,
// and allows the output to be easily refined
MultiLogger interface {
// New returns a new Logger that has this logger's context plus the given context
New(ctx ...interface{}) MultiLogger
// SetHandler updates the logger to write records to the specified handler.
SetHandler(h LogHandler)
// Set the stack depth for the logger
SetStackDepth(int) MultiLogger
// Log a message at the given level with context key/value pairs
Debug(msg string, ctx ...interface{})
// Log a message at the given level formatting message with the parameters
Debugf(msg string, params ...interface{})
// Log a message at the given level with context key/value pairs
Info(msg string, ctx ...interface{})
// Log a message at the given level formatting message with the parameters
Infof(msg string, params ...interface{})
// Log a message at the given level with context key/value pairs
Warn(msg string, ctx ...interface{})
// Log a message at the given level formatting message with the parameters
Warnf(msg string, params ...interface{})
// Log a message at the given level with context key/value pairs
Error(msg string, ctx ...interface{})
// Log a message at the given level formatting message with the parameters
Errorf(msg string, params ...interface{})
// Log a message at the given level with context key/value pairs
Crit(msg string, ctx ...interface{})
// Log a message at the given level formatting message with the parameters
Critf(msg string, params ...interface{})
// Log a message at the given level with context key/value pairs and exits
Fatal(msg string, ctx ...interface{})
// Log a message at the given level formatting message with the parameters and exits
Fatalf(msg string, params ...interface{})
// Log a message at the given level with context key/value pairs and panics
Panic(msg string, ctx ...interface{})
// Log a message at the given level formatting message with the parameters and panics
Panicf(msg string, params ...interface{})
}
// The log handler interface
LogHandler interface {
Log(*Record) error
//log15.Handler
}
// The log stack handler interface
LogStackHandler interface {
LogHandler
GetStack() int
}
// The log handler interface which has child logs
ParentLogHandler interface {
SetChild(handler LogHandler) LogHandler
}
// The log format interface
LogFormat interface {
Format(r *Record) []byte
}
// The log level type
LogLevel int
// Used for the callback to LogFunctionMap
LogOptions struct {
Ctx *config.Context
ReplaceExistingHandler bool
HandlerWrap ParentLogHandler
Levels []LogLevel
ExtendedOptions map[string]interface{}
}
// The log record
Record struct {
Message string // The message
Time time.Time // The time
Level LogLevel //The level
Call CallStack // The call stack if built
Context ContextMap // The context
}
// The lazy structure to implement a function to be invoked only if needed
Lazy struct {
Fn interface{} // the function
}
// Currently the only requirement for the callstack is to support the Formatter method
// which stack.Call does so we use that
CallStack interface {
fmt.Formatter // Requirement
}
)
// FormatFunc returns a new Format object which uses
// the given function to perform record formatting.
func FormatFunc(f func(*Record) []byte) LogFormat {
return formatFunc(f)
}
type formatFunc func(*Record) []byte
func (f formatFunc) Format(r *Record) []byte {
return f(r)
}
func NewRecord(message string, level LogLevel) *Record {
return &Record{Message: message, Context: ContextMap{}, Level: level}
}
const (
LvlCrit LogLevel = iota // Critical
LvlError // Error
LvlWarn // Warning
LvlInfo // Information
LvlDebug // Debug
)
// A list of all the log levels
var LvlAllList = []LogLevel{LvlDebug, LvlInfo, LvlWarn, LvlError, LvlCrit}
// Implements the ParentLogHandler
type parentLogHandler struct {
setChild func(handler LogHandler) LogHandler
}
// Create a new parent log handler
func NewParentLogHandler(callBack func(child LogHandler) LogHandler) ParentLogHandler {
return &parentLogHandler{callBack}
}
// Sets the child of the log handler
func (p *parentLogHandler) SetChild(child LogHandler) LogHandler {
return p.setChild(child)
}
// Create a new log options
func NewLogOptions(cfg *config.Context, replaceHandler bool, phandler ParentLogHandler, lvl ...LogLevel) (logOptions *LogOptions) {
logOptions = &LogOptions{
Ctx: cfg,
ReplaceExistingHandler: replaceHandler,
HandlerWrap: phandler,
Levels: lvl,
ExtendedOptions: map[string]interface{}{},
}
return
}
// Assumes options will be an even number and have a string, value syntax
func (l *LogOptions) SetExtendedOptions(options ...interface{}) {
for x := 0; x < len(options); x += 2 {
l.ExtendedOptions[options[x].(string)] = options[x+1]
}
}
// Gets a string option with default
func (l *LogOptions) GetStringDefault(option, value string) string {
if v, found := l.ExtendedOptions[option]; found {
return v.(string)
}
return value
}
// Gets an int option with default
func (l *LogOptions) GetIntDefault(option string, value int) int {
if v, found := l.ExtendedOptions[option]; found {
return v.(int)
}
return value
}
// Gets a boolean option with default
func (l *LogOptions) GetBoolDefault(option string, value bool) bool {
if v, found := l.ExtendedOptions[option]; found {
return v.(bool)
}
return value
}
|