github.com/bibaroc/wingman@v0.0.2-0.20200911182922-33c2085136b1/pkg/logger/logger.go (about) 1 package logger 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "os" 8 "sync" 9 10 "github.com/bibaroc/wingman/pkg" 11 ) 12 13 type LogLevel int 14 15 const ( 16 FATAL LogLevel = iota // [FATA] 17 ERROR // [ERRO] 18 WARNING // [WARN] 19 INFO // [INFO] 20 DEBUG // [DEBU] 21 TRACE // [TRAC] 22 ) 23 24 const ( 25 WithCallerInfo = 1 << iota 26 ) 27 28 var ( 29 _ pkg.Logger = (*Log)(nil) 30 ) 31 32 type Log struct { 33 level LogLevel 34 out io.Writer 35 flags int 36 buff cbuff 37 b sync.Pool 38 sync.Mutex 39 } 40 41 func (l *Log) Panic(v ...interface{}) { 42 panic(l.write(ERROR, v...)) 43 } 44 func (l *Log) Panicf(format string, v ...interface{}) { 45 panic(l.writef(ERROR, format, v...)) 46 } 47 func (l *Log) Panicln(v ...interface{}) { 48 panic(l.writeln(ERROR, v...)) 49 } 50 51 func (l *Log) Fatal(v ...interface{}) { 52 if err := l.write(ERROR, v...); err != nil { 53 fmt.Println(err) 54 } 55 os.Exit(1) 56 } 57 func (l *Log) Fatalf(format string, v ...interface{}) { 58 if err := l.writef(ERROR, format, v...); err != nil { 59 fmt.Println(err) 60 } 61 os.Exit(1) 62 } 63 func (l *Log) Fatalln(v ...interface{}) { 64 if err := l.writeln(ERROR, v...); err != nil { 65 fmt.Println(err) 66 } 67 os.Exit(1) 68 } 69 70 func (l *Log) Error(v ...interface{}) { 71 if l.level < ERROR { 72 return 73 } 74 if err := l.write(ERROR, v...); err != nil { 75 fmt.Println(err) 76 } 77 } 78 func (l *Log) Errorf(format string, v ...interface{}) { 79 if l.level < ERROR { 80 return 81 } 82 if err := l.writef(ERROR, format, v...); err != nil { 83 fmt.Println(err) 84 } 85 } 86 func (l *Log) Errorln(v ...interface{}) { 87 if l.level < ERROR { 88 return 89 } 90 if err := l.writeln(ERROR, v...); err != nil { 91 fmt.Println(err) 92 } 93 } 94 95 func (l *Log) Warn(v ...interface{}) { 96 if l.level < WARNING { 97 return 98 } 99 if err := l.write(WARNING, v...); err != nil { 100 fmt.Println(err) 101 } 102 } 103 func (l *Log) Warnf(format string, v ...interface{}) { 104 if l.level < WARNING { 105 return 106 } 107 if err := l.writef(WARNING, format, v...); err != nil { 108 fmt.Println(err) 109 } 110 } 111 func (l *Log) Warnln(v ...interface{}) { 112 if l.level < WARNING { 113 return 114 } 115 if err := l.writeln(WARNING, v...); err != nil { 116 fmt.Println(err) 117 } 118 } 119 120 func (l *Log) Info(v ...interface{}) { 121 if l.level < INFO { 122 return 123 } 124 if err := l.write(INFO, v...); err != nil { 125 fmt.Println(err) 126 } 127 } 128 func (l *Log) Infof(format string, v ...interface{}) { 129 if l.level < INFO { 130 return 131 } 132 if err := l.writef(INFO, format, v...); err != nil { 133 fmt.Println(err) 134 } 135 } 136 func (l *Log) Infoln(v ...interface{}) { 137 if l.level < INFO { 138 return 139 } 140 if err := l.writeln(INFO, v...); err != nil { 141 fmt.Println(err) 142 } 143 } 144 145 func (l *Log) Debug(v ...interface{}) { 146 if l.level < DEBUG { 147 return 148 } 149 if err := l.write(DEBUG, v...); err != nil { 150 fmt.Println(err) 151 } 152 } 153 func (l *Log) Debugf(format string, v ...interface{}) { 154 if l.level < DEBUG { 155 return 156 } 157 if err := l.writef(DEBUG, format, v...); err != nil { 158 fmt.Println(err) 159 } 160 } 161 func (l *Log) Debugln(v ...interface{}) { 162 if l.level < DEBUG { 163 return 164 } 165 if err := l.writeln(DEBUG, v...); err != nil { 166 fmt.Println(err) 167 } 168 } 169 170 func (l *Log) Trace(v ...interface{}) { 171 if l.level < TRACE { 172 return 173 } 174 if err := l.write(TRACE, v...); err != nil { 175 fmt.Println(err) 176 } 177 } 178 func (l *Log) Tracef(format string, v ...interface{}) { 179 if l.level < TRACE { 180 return 181 } 182 if err := l.writef(TRACE, format, v...); err != nil { 183 fmt.Println(err) 184 } 185 } 186 func (l *Log) Traceln(v ...interface{}) { 187 if l.level < TRACE { 188 return 189 } 190 if err := l.writeln(TRACE, v...); err != nil { 191 fmt.Println(err) 192 } 193 } 194 195 func (l *Log) Print(v ...interface{}) { 196 if err := l.write(ERROR, v...); err != nil { 197 fmt.Println(err) 198 } 199 } 200 func (l *Log) Printf(format string, v ...interface{}) { 201 if err := l.writef(ERROR, format, v...); err != nil { 202 fmt.Println(err) 203 } 204 } 205 func (l *Log) Println(v ...interface{}) { 206 if err := l.writeln(ERROR, v...); err != nil { 207 fmt.Println(err) 208 } 209 } 210 func (l *Log) caller() string { 211 if l.flags&WithCallerInfo == 0 { 212 return "-" 213 } 214 const SKIPCALLERS = 3 215 const NOTFOUND = "n/a" 216 217 c := []uintptr{0} 218 if callers(SKIPCALLERS, c) == 0 { 219 return NOTFOUND 220 } 221 222 fnc := findfunc(c[0]) 223 if !fnc.valid() { 224 return NOTFOUND 225 } 226 227 fnName := funcname(fnc) 228 for i := len(fnName) - 1; i >= 0; i-- { 229 if os.IsPathSeparator(fnName[i]) { 230 return fnName[i+1:] 231 } 232 } 233 return fnName 234 } 235 236 func (l *Log) write(level LogLevel, args ...interface{}) error { 237 callerInfo := l.caller() 238 239 buff := l.b.Get().(*bytes.Buffer) 240 buff.Reset() 241 242 buff.WriteString(level.String()) 243 buff.WriteByte(' ') 244 buff.WriteString(callerInfo) 245 buff.WriteByte(' ') 246 247 fmt.Fprint(buff, args...) 248 249 l.Lock() 250 _, err := l.out.Write(buff.Bytes()) 251 l.Unlock() 252 253 l.b.Put(buff) 254 return err 255 } 256 func (l *Log) writeln(level LogLevel, args ...interface{}) error { 257 callerInfo := l.caller() 258 259 buff := l.b.Get().(*bytes.Buffer) 260 buff.Reset() 261 262 buff.WriteString(level.String()) 263 buff.WriteByte(' ') 264 buff.WriteString(callerInfo) 265 buff.WriteByte(' ') 266 267 fmt.Fprintln(buff, args...) 268 269 l.Lock() 270 _, err := l.out.Write(buff.Bytes()) 271 l.Unlock() 272 273 l.b.Put(buff) 274 275 return err 276 } 277 func (l *Log) writef(level LogLevel, format string, args ...interface{}) error { 278 callerInfo := l.caller() 279 280 buff := l.b.Get().(*bytes.Buffer) 281 buff.Reset() 282 283 buff.WriteString(level.String()) 284 buff.WriteByte(' ') 285 buff.WriteString(callerInfo) 286 buff.WriteByte(' ') 287 288 fmt.Fprintf(buff, format, args...) 289 l.Lock() 290 _, err := l.out.Write(buff.Bytes()) 291 l.Unlock() 292 293 l.b.Put(buff) 294 return err 295 } 296 297 func NewLogger( 298 level LogLevel, 299 writer io.Writer, 300 flags int, 301 ) *Log { 302 return &Log{ 303 level: level, 304 out: writer, 305 flags: flags, 306 b: sync.Pool{ 307 New: func() interface{} { 308 return bytes.NewBuffer(make([]byte, 0, 10*1<<10)) 309 }, 310 }, 311 } 312 } 313 314 func NewDebugLogger() *Log { 315 return NewLogger( 316 DEBUG, 317 os.Stdout, 318 WithCallerInfo, 319 ) 320 }