github.com/jd-ly/cmd@v1.0.10/logger/revel_logger.go (about) 1 package logger 2 3 import ( 4 "fmt" 5 "github.com/revel/log15" 6 "log" 7 "os" 8 ) 9 10 // This type implements the MultiLogger 11 type RevelLogger struct { 12 log15.Logger 13 } 14 15 // Set the systems default logger 16 // Default logs will be captured and handled by revel at level info 17 func SetDefaultLog(fromLog MultiLogger) { 18 log.SetOutput(loggerRewrite{Logger: fromLog, Level: log15.LvlInfo, hideDeprecated: true}) 19 // No need to show date and time, that will be logged with revel 20 log.SetFlags(0) 21 } 22 23 func (rl *RevelLogger) Debugf(msg string, param ...interface{}) { 24 rl.Debug(fmt.Sprintf(msg, param...)) 25 } 26 27 // Print a formatted info message 28 func (rl *RevelLogger) Infof(msg string, param ...interface{}) { 29 rl.Info(fmt.Sprintf(msg, param...)) 30 } 31 32 // Print a formatted warn message 33 func (rl *RevelLogger) Warnf(msg string, param ...interface{}) { 34 rl.Warn(fmt.Sprintf(msg, param...)) 35 } 36 37 // Print a formatted error message 38 func (rl *RevelLogger) Errorf(msg string, param ...interface{}) { 39 rl.Error(fmt.Sprintf(msg, param...)) 40 } 41 42 // Print a formatted critical message 43 func (rl *RevelLogger) Critf(msg string, param ...interface{}) { 44 rl.Crit(fmt.Sprintf(msg, param...)) 45 } 46 47 // Print a formatted fatal message 48 func (rl *RevelLogger) Fatalf(msg string, param ...interface{}) { 49 rl.Fatal(fmt.Sprintf(msg, param...)) 50 } 51 52 // Print a formatted panic message 53 func (rl *RevelLogger) Panicf(msg string, param ...interface{}) { 54 rl.Panic(fmt.Sprintf(msg, param...)) 55 } 56 57 // Print a critical message and call os.Exit(1) 58 func (rl *RevelLogger) Fatal(msg string, ctx ...interface{}) { 59 rl.Crit(msg, ctx...) 60 os.Exit(1) 61 } 62 63 // Print a critical message and panic 64 func (rl *RevelLogger) Panic(msg string, ctx ...interface{}) { 65 rl.Crit(msg, ctx...) 66 panic(msg) 67 } 68 69 // Override log15 method 70 func (rl *RevelLogger) New(ctx ...interface{}) MultiLogger { 71 old := &RevelLogger{Logger: rl.Logger.New(ctx...)} 72 return old 73 } 74 75 // Set the stack level to check for the caller 76 func (rl *RevelLogger) SetStackDepth(amount int) MultiLogger { 77 rl.Logger.SetStackDepth(amount) // Ignore the logger returned 78 return rl 79 } 80 81 // Create a new logger 82 func New(ctx ...interface{}) MultiLogger { 83 r := &RevelLogger{Logger: log15.New(ctx...)} 84 r.SetStackDepth(0) 85 return r 86 } 87 88 // Set the handler in the Logger 89 func (rl *RevelLogger) SetHandler(h LogHandler) { 90 rl.Logger.SetHandler(callHandler(h.Log)) 91 } 92 93 // The function wrapper to implement the callback 94 type callHandler func(r *Record) error 95 96 // Log implementation, reads the record and extracts the details from the log record 97 // Hiding the implementation. 98 func (c callHandler) Log(log *log15.Record) error { 99 ctx := log.Ctx 100 var ctxMap ContextMap 101 if len(ctx) > 0 { 102 ctxMap = make(ContextMap, len(ctx) / 2) 103 104 for i := 0; i < len(ctx); i += 2 { 105 v := ctx[i] 106 key, ok := v.(string) 107 if !ok { 108 key = fmt.Sprintf("LOGGER_INVALID_KEY %v", v) 109 } 110 var value interface{} 111 if len(ctx) > i + 1 { 112 value = ctx[i + 1] 113 } else { 114 value = "LOGGER_VALUE_MISSING" 115 } 116 ctxMap[key] = value 117 } 118 } else { 119 ctxMap = make(ContextMap, 0) 120 } 121 r := &Record{Message: log.Msg, Context: ctxMap, Time: log.Time, Level: LogLevel(log.Lvl), Call: CallStack(log.Call)} 122 return c(r) 123 } 124 125 // Internally used contextMap, allows conversion of map to map[string]string 126 type ContextMap map[string]interface{} 127 128 // Convert the context map to be string only values, any non string values are ignored 129 func (m ContextMap) StringMap() (newMap map[string]string) { 130 if m != nil { 131 newMap = map[string]string{} 132 for key, value := range m { 133 if svalue, isstring := value.(string); isstring { 134 newMap[key] = svalue 135 } 136 } 137 } 138 return 139 } 140 func (m ContextMap) Add(key string, value interface{}) { 141 m[key] = value 142 }