github.com/scottcagno/storage@v1.8.0/pkg/_junk/_logger/logger.go (about) 1 package logger 2 3 import ( 4 "bytes" 5 "fmt" 6 "log" 7 "os" 8 "path/filepath" 9 "runtime" 10 "strings" 11 "sync" 12 ) 13 14 const ( 15 White = iota 16 Black = iota + 30 17 Red 18 Green 19 Yellow 20 Blue 21 Purple 22 Cyan 23 Grey 24 ) 25 26 const ( 27 levelDefault = iota 28 levelTrace 29 levelDebug 30 levelInfo 31 levelWarn 32 levelError 33 levelFatal 34 levelPanic 35 ) 36 37 const ( 38 color = iota 39 prefix 40 ) 41 42 var colors = map[int]string{ 43 White: "\033[0m", // \033[0m 44 Black: "\033[30m", // \033[30m 45 Red: "\033[31m", // \033[31m 46 Green: "\033[32m", // \033[32m 47 Yellow: "\033[33m", // \033[33m 48 Blue: "\033[34m", // \033[34m 49 Purple: "\033[35m", // \033[35m 50 Cyan: "\033[36m", // \033[36m 51 Grey: "\033[37m", // \033[37m 52 } 53 54 var levels = map[int][2]string{ 55 levelTrace: {colors[Grey], "TRCE"}, 56 levelDebug: {colors[Grey], "DBUG"}, 57 levelInfo: {colors[Blue], "INFO"}, 58 levelWarn: {colors[Yellow], "WARN"}, 59 levelError: {colors[Red], "EROR"}, 60 levelFatal: {colors[Red], "FATL"}, 61 levelPanic: {colors[Red], "PANC"}, 62 levelDefault: {colors[White], "NORM"}, 63 } 64 65 // date or time format ref -> f1, f2 := "2006/01/02:15:04:05Z07", "2006-01-02 15:04:05Z07" 66 // t := time.Now() 67 // s1 := t.Format(f1) 68 69 var DefaultLogger = NewLogger() 70 71 type Logger struct { 72 lock sync.Mutex // sync 73 log *log.Logger // actual logger 74 buf *bytes.Buffer // buffer 75 printFunc bool 76 printFile bool 77 dep int // call depth 78 } 79 80 func NewLogger() *Logger { 81 _ = log.Ldate | log.Ltime | log.Lshortfile | log.Lmsgprefix 82 l := &Logger{ 83 log: log.New(os.Stderr, "", log.LstdFlags), 84 buf: new(bytes.Buffer), 85 dep: 5, 86 } 87 return l 88 } 89 90 func (l *Logger) logInternal(level, depth int, format string, args ...interface{}) { 91 l.lock.Lock() 92 defer l.lock.Unlock() 93 levelInfo, ok := levels[level] 94 if !ok { 95 levelInfo = levels[levelDefault] 96 } 97 l.buf.Reset() 98 l.buf.WriteString("| ") 99 l.buf.WriteString(levelInfo[color]) 100 l.buf.WriteString(levelInfo[prefix]) 101 l.buf.WriteString(colors[White]) 102 l.buf.WriteString(" | ") 103 if l.printFunc || l.printFile { 104 if level == levelFatal { 105 depth += 1 106 } 107 if level != levelPanic { 108 fn, file := trace(depth) 109 if l.printFunc { 110 l.buf.WriteByte('[') 111 l.buf.WriteString(strings.Split(fn, ".")[1]) 112 l.buf.WriteByte(']') 113 } 114 if l.printFunc && l.printFile { 115 l.buf.WriteByte(' ') 116 } 117 if l.printFile { 118 l.buf.WriteString(file) 119 } 120 l.buf.WriteString(" - ") 121 } 122 } 123 l.buf.WriteString(format) 124 if args == nil || len(args) == 0 { 125 l.log.Print(l.buf.String()) 126 return 127 } 128 l.log.Printf(l.buf.String(), args...) 129 } 130 131 func (l *Logger) SetPrefix(prefix string) { 132 l.lock.Lock() 133 defer l.lock.Unlock() 134 l.log.SetPrefix(prefix) 135 } 136 137 func (l *Logger) SetPrintFunc(ok bool) { 138 l.lock.Lock() 139 defer l.lock.Unlock() 140 l.printFunc = ok 141 } 142 143 func (l *Logger) SetPrintFile(ok bool) { 144 l.lock.Lock() 145 defer l.lock.Unlock() 146 l.printFile = ok 147 } 148 149 func (l *Logger) SetCallDepth(depth int) { 150 l.lock.Lock() 151 defer l.lock.Unlock() 152 l.dep = depth 153 } 154 155 func (l *Logger) Trace(message string) { 156 l.logInternal(levelTrace, l.dep, message) 157 } 158 159 func (l *Logger) Tracef(format string, args ...interface{}) { 160 l.logInternal(levelTrace, l.dep, format, args...) 161 } 162 163 func (l *Logger) Debug(message string) { 164 l.logInternal(levelDebug, l.dep, message) 165 } 166 167 func (l *Logger) Debugf(format string, args ...interface{}) { 168 l.logInternal(levelDebug, l.dep, format, args...) 169 } 170 171 func (l *Logger) Info(message string) { 172 l.logInternal(levelInfo, l.dep, message) 173 } 174 175 func (l *Logger) Infof(format string, args ...interface{}) { 176 l.logInternal(levelInfo, l.dep, format, args...) 177 } 178 179 func (l *Logger) Warn(message string) { 180 l.logInternal(levelWarn, l.dep, message) 181 } 182 183 func (l *Logger) Warnf(format string, args ...interface{}) { 184 l.logInternal(levelWarn, l.dep, format, args...) 185 } 186 187 func (l *Logger) Error(message string) { 188 l.logInternal(levelError, l.dep, message) 189 } 190 191 func (l *Logger) Errorf(format string, args ...interface{}) { 192 l.logInternal(levelError, l.dep, format, args...) 193 } 194 195 func (l *Logger) Fatal(message string) { 196 l.logInternal(levelFatal, l.dep, message) 197 os.Exit(1) 198 } 199 200 func (l *Logger) Fatalf(format string, args ...interface{}) { 201 l.logInternal(levelFatal, l.dep, format, args...) 202 os.Exit(1) 203 } 204 205 func (l *Logger) Panic(message string) { 206 l.logInternal(levelPanic, l.dep, message) 207 panic(message) 208 } 209 210 func (l *Logger) Panicf(format string, args ...interface{}) { 211 l.logInternal(levelPanic, l.dep, format, args...) 212 panic(fmt.Sprintf(format, args...)) 213 } 214 215 func (l *Logger) Print(message string) { 216 l.logInternal(levelDefault, l.dep, message) 217 } 218 219 func (l *Logger) Printf(format string, args ...interface{}) { 220 l.logInternal(levelDefault, l.dep, format, args...) 221 } 222 223 func trace0(calldepth int) (string, string) { 224 //pc, file, line, ok := runtime.Caller(calldepth) 225 pc, file, line, _ := runtime.Caller(calldepth) 226 fn := runtime.FuncForPC(pc) 227 //funcName := filepath.Base(fn.Name()) 228 //fileName := filepath.Base(file) 229 //return fmt.Sprintf("%s %s:%d", funcName, fileName, line) 230 return filepath.Base(fn.Name()), fmt.Sprintf("%s:%d", filepath.Base(file), line) 231 } 232 233 func trace(calldepth int) (string, string) { 234 pc := make([]uintptr, 10) // at least 1 entry needed 235 runtime.Callers(calldepth, pc) 236 fn := runtime.FuncForPC(pc[0]) 237 file, line := fn.FileLine(pc[0]) 238 //sfile := strings.Split(file, "/") 239 //sname := strings.Split(f.Name(), "/") 240 return filepath.Base(fn.Name()), fmt.Sprintf("%s:%d", filepath.Base(file), line) 241 }