gitee.com/quant1x/gox@v1.7.6/logger/logger.go (about) 1 package logger 2 3 import ( 4 "bytes" 5 "context" 6 "fmt" 7 "gitee.com/quant1x/gox/api" 8 "gitee.com/quant1x/gox/exception" 9 "gitee.com/quant1x/gox/mdc" 10 "gitee.com/quant1x/gox/signal" 11 "os" 12 "path/filepath" 13 "reflect" 14 "runtime" 15 "time" 16 ) 17 18 const ( 19 DEBUG LogLevel = iota 20 INFO 21 WARN 22 ERROR 23 OFF 24 FATAL 25 ) 26 27 // 日志默认以天为单位 28 const ( 29 // 保持7天 [wangfeng on 2018/12/25 12:38] 30 __logger_roller_days int = 7 31 //__logget_global_skip = 3 32 __logger_local_skip = 2 33 // 时间戳 - 毫秒 34 Timestamp = "2006-01-02T15:04:05.000" 35 //traceID 36 __logger_traceId = mdc.APP_TRACEID 37 ) 38 39 var ( 40 __logger_path string 41 ) 42 43 var ( 44 logLevel LogLevel = DEBUG 45 46 logQueue = make(chan *logValue, 10000) 47 loggerMap = make(map[string]*Logger) 48 writeDone = make(chan bool) 49 50 currUnixTime int64 51 currDateTime string 52 currDateHour string 53 currDateDay string 54 ) 55 56 type Logger struct { 57 name string 58 writer LogWriter 59 } 60 type LogLevel uint8 61 62 type logValue struct { 63 level LogLevel 64 value []byte 65 fileNo string 66 writer LogWriter 67 } 68 69 func init() { 70 now := time.Now() 71 currUnixTime = now.Unix() 72 currDateTime = now.Format(Timestamp) 73 currDateHour = now.Format("2006010215") 74 currDateDay = now.Format("20060102") 75 go func() { 76 tm := time.NewTimer(time.Millisecond) 77 if err := recover(); err != nil { // avoid timer panic 78 } 79 for { 80 now := time.Now() 81 d := time.Second - time.Duration(now.Nanosecond()) 82 tm.Reset(d) 83 <-tm.C 84 now = time.Now() 85 currUnixTime = now.Unix() 86 currDateTime = now.Format(Timestamp) 87 currDateHour = now.Format("2006010215") 88 currDateDay = now.Format("20060102") 89 } 90 }() 91 go flushLog(true) 92 93 //创建监听退出chan 94 sigs := signal.Notify() 95 96 _, cancel := context.WithCancel(context.Background()) 97 98 go func() { 99 s := <-sigs 100 Infof("exit sign, [%+v]", s) 101 FlushLogger() 102 fmt.Println("exit", s) 103 cancel() 104 os.Exit(0) 105 }() 106 107 } 108 109 func (lv *LogLevel) String() string { 110 switch *lv { 111 case DEBUG: 112 return "DEBUG" 113 case INFO: 114 return "INFO" 115 case WARN: 116 return "WARN" 117 case ERROR: 118 return "ERROR" 119 case FATAL: 120 return "FATAL" 121 default: 122 return "UNKNOWN" 123 } 124 } 125 126 // SetLogPath 设置日志路径, 默认是INFO级别日志 127 // 128 // Deprecated: 推荐使用 InitLogger 129 func SetLogPath(path string) { 130 InitLogger(path, INFO) 131 } 132 133 // InitLogger 初始化 134 func InitLogger(path string, level ...LogLevel) { 135 // 日志路径非空, 赋值 136 if !api.IsEmpty(path) { 137 __logger_path = path 138 } 139 140 // 日志级别默认是INFO 141 __opt_level := INFO 142 if len(level) > 0 { 143 __opt_level = level[0] 144 } 145 SetLevel(__opt_level) 146 } 147 148 // GetLogger return an logger instance 149 func GetLogger(name string) *Logger { 150 if lg, ok := loggerMap[name]; ok { 151 return lg 152 } 153 lg := &Logger{ 154 name: name, 155 writer: &ConsoleWriter{}, 156 } 157 _ = lg.SetDayRoller(__logger_path, __logger_roller_days) 158 loggerMap[name] = lg 159 return lg 160 } 161 162 func SetLevel(level LogLevel) { 163 logLevel = level 164 } 165 166 // IsDebug 是否DEBUG模式 167 func IsDebug() bool { 168 if DEBUG < logLevel { 169 return false 170 } 171 return true 172 } 173 174 func StringToLevel(level string) LogLevel { 175 switch level { 176 case "DEBUG": 177 return DEBUG 178 case "INFO": 179 return INFO 180 case "WARN": 181 return WARN 182 case "ERROR": 183 return ERROR 184 case "FATAL": 185 return FATAL 186 default: 187 return DEBUG 188 } 189 } 190 191 func (l *Logger) SetLogName(name string) { 192 l.name = name 193 } 194 195 func (l *Logger) SetFileRoller(logpath string, num int, sizeMB int) error { 196 if err := os.MkdirAll(logpath, 0755); err != nil { 197 panic(err) 198 } 199 w := NewRollFileWriter(logpath, l.name, num, sizeMB) 200 l.writer = w 201 return nil 202 } 203 204 func (l *Logger) IsConsoleWriter() bool { 205 if reflect.TypeOf(l.writer) == reflect.TypeOf(&ConsoleWriter{}) { 206 return true 207 } 208 return false 209 } 210 211 func (l *Logger) SetWriter(w LogWriter) { 212 l.writer = w 213 } 214 215 func (l *Logger) SetDayRoller(logpath string, num int) error { 216 if err := os.MkdirAll(logpath, 0755); err != nil { 217 return err 218 } 219 w := NewDateWriter(logpath, l.name, DAY, num) 220 l.writer = w 221 return nil 222 } 223 224 func (l *Logger) SetHourRoller(logpath string, num int) error { 225 if err := os.MkdirAll(logpath, 0755); err != nil { 226 return err 227 } 228 w := NewDateWriter(logpath, l.name, HOUR, num) 229 l.writer = w 230 return nil 231 } 232 233 func (l *Logger) SetConsole() { 234 l.writer = &ConsoleWriter{} 235 } 236 237 func (l *Logger) Debug(v ...interface{}) { 238 l.writef(__logger_local_skip, DEBUG, "", v) 239 } 240 241 func (l *Logger) Info(v ...interface{}) { 242 l.writef(__logger_local_skip, INFO, "", v) 243 } 244 245 func (l *Logger) Warn(v ...interface{}) { 246 l.writef(__logger_local_skip, WARN, "", v) 247 } 248 249 func (l *Logger) Error(v ...interface{}) { 250 l.writef(__logger_local_skip, ERROR, "", v) 251 } 252 253 func (l *Logger) Debugf(format string, v ...interface{}) { 254 l.writef(__logger_local_skip, DEBUG, format, v) 255 } 256 257 func (l *Logger) Infof(format string, v ...interface{}) { 258 l.writef(__logger_local_skip, INFO, format, v) 259 } 260 261 func (l *Logger) Warnf(format string, v ...interface{}) { 262 l.writef(__logger_local_skip, WARN, format, v) 263 } 264 265 func (l *Logger) Errorf(format string, v ...interface{}) { 266 l.writef(__logger_local_skip, ERROR, format, v) 267 } 268 269 func (l *Logger) Fatal(v ...interface{}) { 270 l.writef(__logger_local_skip, FATAL, "", v) 271 os.Exit(-1) 272 } 273 274 func (l *Logger) Fatalf(format string, v ...interface{}) { 275 l.writef(__logger_local_skip, FATAL, format, v) 276 os.Exit(-1) 277 } 278 279 func getTraceId() string { 280 traceId := mdc.Get(__logger_traceId) 281 t := reflect.ValueOf(traceId) 282 if t.Kind() == reflect.String { 283 return t.String() 284 } 285 return "" 286 } 287 288 func (l *Logger) writef(skip int, level LogLevel, format string, v []interface{}) { 289 if level < logLevel { 290 return 291 } 292 293 t := time.Now() 294 //ms := (t.UnixNano() / int64(time.Millisecond)) % 1000 295 buf := bytes.NewBuffer(nil) 296 if l.writer.NeedPrefix() { 297 traceId := getTraceId() 298 _, _ = fmt.Fprintf(buf, "%s|%s|", t.Format(Timestamp), traceId) 299 if logLevel == DEBUG { 300 _, file, line, ok := runtime.Caller(skip) 301 if !ok { 302 file = "???" 303 line = 0 304 } else { 305 file = filepath.Base(file) 306 } 307 _, _ = fmt.Fprintf(buf, "%s:%d|", file, line) 308 } 309 } 310 buf.WriteString(level.String()) 311 buf.WriteByte('|') 312 313 if format == "" { 314 _, _ = fmt.Fprint(buf, v...) 315 } else { 316 _, _ = fmt.Fprintf(buf, format, v...) 317 } 318 if l.writer.NeedPrefix() { 319 buf.WriteByte('\n') 320 } 321 logQueue <- &logValue{value: buf.Bytes(), writer: l.writer} 322 } 323 324 func FlushLogger() { 325 flushLog(false) 326 } 327 328 func flushLog(sync bool) { 329 defer exception.PanicIgnore() 330 if sync { 331 for v := range logQueue { 332 v.writer.Write(v.value) 333 } 334 } else { 335 for { 336 select { 337 case v := <-logQueue: 338 v.writer.Write(v.value) 339 continue 340 default: 341 return 342 } 343 } 344 } 345 } 346 347 func Info(v ...interface{}) { 348 logger := GetLogger("runtime") 349 logger.writef(__logger_local_skip, INFO, "", v) 350 } 351 352 func Infof(format string, v ...interface{}) { 353 logger := GetLogger("runtime") 354 logger.writef(__logger_local_skip, INFO, format, v) 355 } 356 357 func Debug(v ...interface{}) { 358 logger := GetLogger("debug") 359 logger.writef(__logger_local_skip, DEBUG, "", v) 360 } 361 362 func Debugf(format string, v ...interface{}) { 363 logger := GetLogger("debug") 364 logger.writef(__logger_local_skip, DEBUG, format, v) 365 } 366 367 func Warn(v ...interface{}) { 368 logger := GetLogger("warn") 369 logger.writef(__logger_local_skip, WARN, "", v) 370 } 371 372 func Warnf(format string, v ...interface{}) { 373 logger := GetLogger("warn") 374 logger.writef(__logger_local_skip, WARN, format, v) 375 } 376 377 func Error(v ...interface{}) { 378 logger := GetLogger("error") 379 logger.writef(__logger_local_skip, ERROR, "", v) 380 } 381 382 func Errorf(format string, v ...interface{}) { 383 logger := GetLogger("error") 384 logger.writef(__logger_local_skip, ERROR, format, v) 385 } 386 387 func Fatal(v ...interface{}) { 388 logger := GetLogger("error") 389 logger.writef(__logger_local_skip, FATAL, "", v) 390 os.Exit(-1) 391 } 392 393 func Fatalf(format string, v ...interface{}) { 394 logger := GetLogger("error") 395 logger.writef(__logger_local_skip, FATAL, format, v) 396 os.Exit(-1) 397 }