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
|
package logger
import (
"fmt"
"github.com/revel/log15"
"log"
"os"
)
// This type implements the MultiLogger
type RevelLogger struct {
log15.Logger
}
// Set the systems default logger
// Default logs will be captured and handled by revel at level info
func SetDefaultLog(fromLog MultiLogger) {
log.SetOutput(loggerRewrite{Logger: fromLog, Level: log15.LvlInfo, hideDeprecated: true})
// No need to show date and time, that will be logged with revel
log.SetFlags(0)
}
func (rl *RevelLogger) Debugf(msg string, param ...interface{}) {
rl.Debug(fmt.Sprintf(msg, param...))
}
// Print a formatted info message
func (rl *RevelLogger) Infof(msg string, param ...interface{}) {
rl.Info(fmt.Sprintf(msg, param...))
}
// Print a formatted warn message
func (rl *RevelLogger) Warnf(msg string, param ...interface{}) {
rl.Warn(fmt.Sprintf(msg, param...))
}
// Print a formatted error message
func (rl *RevelLogger) Errorf(msg string, param ...interface{}) {
rl.Error(fmt.Sprintf(msg, param...))
}
// Print a formatted critical message
func (rl *RevelLogger) Critf(msg string, param ...interface{}) {
rl.Crit(fmt.Sprintf(msg, param...))
}
// Print a formatted fatal message
func (rl *RevelLogger) Fatalf(msg string, param ...interface{}) {
rl.Fatal(fmt.Sprintf(msg, param...))
}
// Print a formatted panic message
func (rl *RevelLogger) Panicf(msg string, param ...interface{}) {
rl.Panic(fmt.Sprintf(msg, param...))
}
// Print a critical message and call os.Exit(1)
func (rl *RevelLogger) Fatal(msg string, ctx ...interface{}) {
rl.Crit(msg, ctx...)
os.Exit(1)
}
// Print a critical message and panic
func (rl *RevelLogger) Panic(msg string, ctx ...interface{}) {
rl.Crit(msg, ctx...)
panic(msg)
}
// Override log15 method
func (rl *RevelLogger) New(ctx ...interface{}) MultiLogger {
old := &RevelLogger{Logger: rl.Logger.New(ctx...)}
return old
}
// Set the stack level to check for the caller
func (rl *RevelLogger) SetStackDepth(amount int) MultiLogger {
rl.Logger.SetStackDepth(amount) // Ignore the logger returned
return rl
}
// Create a new logger
func New(ctx ...interface{}) MultiLogger {
r := &RevelLogger{Logger: log15.New(ctx...)}
//r.SetStackDepth(2)
return r
}
// Set the handler in the Logger
func (rl *RevelLogger) SetHandler(h LogHandler) {
rl.Logger.SetHandler(callHandler(h.Log))
}
// The function wrapper to implement the callback
type callHandler func(r *Record) error
// Log implementation, reads the record and extracts the details from the log record
// Hiding the implementation.
func (c callHandler) Log(log *log15.Record) error {
ctx := log.Ctx
var ctxMap ContextMap
if len(ctx) > 0 {
ctxMap = make(ContextMap, len(ctx)/2)
for i := 0; i < len(ctx); i += 2 {
v := ctx[i]
key, ok := v.(string)
if !ok {
key = fmt.Sprintf("LOGGER_INVALID_KEY %v", v)
}
var value interface{}
if len(ctx) > i+1 {
value = ctx[i+1]
} else {
value = "LOGGER_VALUE_MISSING"
}
ctxMap[key] = value
}
} else {
ctxMap = make(ContextMap, 0)
}
r := &Record{Message: log.Msg, Context: ctxMap, Time: log.Time, Level: LogLevel(log.Lvl), Call: CallStack(log.Call)}
return c(r)
}
// Internally used contextMap, allows conversion of map to map[string]string
type ContextMap map[string]interface{}
// Convert the context map to be string only values, any non string values are ignored
func (m ContextMap) StringMap() (newMap map[string]string) {
if m != nil {
newMap = map[string]string{}
for key, value := range m {
if svalue, isstring := value.(string); isstring {
newMap[key] = svalue
}
}
}
return
}
func (m ContextMap) Add(key string, value interface{}) {
m[key] = value
}
|