github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/ngaut/log/log.go (about) 1 //high level log wrapper, so it can output different log based on level 2 package log 3 4 import ( 5 "fmt" 6 "io" 7 "log" 8 "os" 9 "runtime" 10 "sync" 11 "time" 12 ) 13 14 const ( 15 Ldate = log.Ldate 16 Llongfile = log.Llongfile 17 Lmicroseconds = log.Lmicroseconds 18 Lshortfile = log.Lshortfile 19 LstdFlags = log.LstdFlags 20 Ltime = log.Ltime 21 ) 22 23 type ( 24 LogLevel int 25 LogType int 26 ) 27 28 const ( 29 LOG_FATAL = LogType(0x1) 30 LOG_ERROR = LogType(0x2) 31 LOG_WARNING = LogType(0x4) 32 LOG_INFO = LogType(0x8) 33 LOG_DEBUG = LogType(0x10) 34 ) 35 36 const ( 37 LOG_LEVEL_NONE = LogLevel(0x0) 38 LOG_LEVEL_FATAL = LOG_LEVEL_NONE | LogLevel(LOG_FATAL) 39 LOG_LEVEL_ERROR = LOG_LEVEL_FATAL | LogLevel(LOG_ERROR) 40 LOG_LEVEL_WARN = LOG_LEVEL_ERROR | LogLevel(LOG_WARNING) 41 LOG_LEVEL_INFO = LOG_LEVEL_WARN | LogLevel(LOG_INFO) 42 LOG_LEVEL_DEBUG = LOG_LEVEL_INFO | LogLevel(LOG_DEBUG) 43 LOG_LEVEL_ALL = LOG_LEVEL_DEBUG 44 ) 45 46 const FORMAT_TIME_DAY string = "20060102" 47 const FORMAT_TIME_HOUR string = "2006010215" 48 49 var _log *logger = New() 50 51 func init() { 52 SetLevel(LOG_LEVEL_ERROR) 53 SetFlags(Ldate | Ltime | Lshortfile) 54 SetHighlighting(runtime.GOOS != "windows") 55 } 56 57 func Logger() *log.Logger { 58 return _log._log 59 } 60 61 func SetLevel(level LogLevel) { 62 _log.SetLevel(level) 63 } 64 func GetLogLevel() LogLevel { 65 return _log.level 66 } 67 68 func SetOutput(out io.Writer) { 69 _log.SetOutput(out) 70 } 71 72 func SetOutputByName(path string) error { 73 return _log.SetOutputByName(path) 74 } 75 76 func SetFlags(flags int) { 77 _log._log.SetFlags(flags) 78 } 79 80 func Info(v ...interface{}) { 81 _log.Info(v...) 82 } 83 84 func Infof(format string, v ...interface{}) { 85 _log.Infof(format, v...) 86 } 87 88 func Debug(v ...interface{}) { 89 _log.Debug(v...) 90 } 91 92 func Debugf(format string, v ...interface{}) { 93 _log.Debugf(format, v...) 94 } 95 96 func Warn(v ...interface{}) { 97 _log.Warning(v...) 98 } 99 100 func Warnf(format string, v ...interface{}) { 101 _log.Warningf(format, v...) 102 } 103 104 func Warning(v ...interface{}) { 105 _log.Warning(v...) 106 } 107 108 func Warningf(format string, v ...interface{}) { 109 _log.Warningf(format, v...) 110 } 111 112 func Error(v ...interface{}) { 113 _log.Error(v...) 114 } 115 116 func Errorf(format string, v ...interface{}) { 117 _log.Errorf(format, v...) 118 } 119 120 func Fatal(v ...interface{}) { 121 _log.Fatal(v...) 122 } 123 124 func Fatalf(format string, v ...interface{}) { 125 _log.Fatalf(format, v...) 126 } 127 128 func SetLevelByString(level string) { 129 _log.SetLevelByString(level) 130 } 131 132 func SetHighlighting(highlighting bool) { 133 _log.SetHighlighting(highlighting) 134 } 135 136 func SetRotateByDay() { 137 _log.SetRotateByDay() 138 } 139 140 func SetRotateByHour() { 141 _log.SetRotateByHour() 142 } 143 144 type logger struct { 145 _log *log.Logger 146 level LogLevel 147 highlighting bool 148 149 dailyRolling bool 150 hourRolling bool 151 152 fileName string 153 logSuffix string 154 fd *os.File 155 156 lock sync.Mutex 157 } 158 159 func (l *logger) SetHighlighting(highlighting bool) { 160 l.highlighting = highlighting 161 } 162 163 func (l *logger) SetLevel(level LogLevel) { 164 l.level = level 165 } 166 167 func (l *logger) SetLevelByString(level string) { 168 l.level = StringToLogLevel(level) 169 } 170 171 func (l *logger) SetRotateByDay() { 172 l.dailyRolling = true 173 l.logSuffix = genDayTime(time.Now()) 174 } 175 176 func (l *logger) SetRotateByHour() { 177 l.hourRolling = true 178 l.logSuffix = genHourTime(time.Now()) 179 } 180 181 func (l *logger) rotate() error { 182 l.lock.Lock() 183 defer l.lock.Unlock() 184 185 var suffix string 186 if l.dailyRolling { 187 suffix = genDayTime(time.Now()) 188 } else if l.hourRolling { 189 suffix = genHourTime(time.Now()) 190 } else { 191 return nil 192 } 193 194 // Notice: if suffix is not equal to l.LogSuffix, then rotate 195 if suffix != l.logSuffix { 196 err := l.doRotate(suffix) 197 if err != nil { 198 return err 199 } 200 } 201 202 return nil 203 } 204 205 func (l *logger) doRotate(suffix string) error { 206 // Notice: Not check error, is this ok? 207 l.fd.Close() 208 209 lastFileName := l.fileName + "." + l.logSuffix 210 err := os.Rename(l.fileName, lastFileName) 211 if err != nil { 212 return err 213 } 214 215 err = l.SetOutputByName(l.fileName) 216 if err != nil { 217 return err 218 } 219 220 l.logSuffix = suffix 221 222 return nil 223 } 224 225 func (l *logger) SetOutput(out io.Writer) { 226 l._log = log.New(out, l._log.Prefix(), l._log.Flags()) 227 } 228 229 func (l *logger) SetOutputByName(path string) error { 230 f, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666) 231 if err != nil { 232 log.Fatal(err) 233 } 234 235 l.SetOutput(f) 236 237 l.fileName = path 238 l.fd = f 239 240 return err 241 } 242 243 func (l *logger) log(t LogType, v ...interface{}) { 244 if l.level|LogLevel(t) != l.level { 245 return 246 } 247 248 err := l.rotate() 249 if err != nil { 250 fmt.Fprintf(os.Stderr, "%s\n", err.Error()) 251 return 252 } 253 254 v1 := make([]interface{}, len(v)+2) 255 logStr, logColor := LogTypeToString(t) 256 if l.highlighting { 257 v1[0] = "\033" + logColor + "m[" + logStr + "]" 258 copy(v1[1:], v) 259 v1[len(v)+1] = "\033[0m" 260 } else { 261 v1[0] = "[" + logStr + "]" 262 copy(v1[1:], v) 263 v1[len(v)+1] = "" 264 } 265 266 s := fmt.Sprintln(v1...) 267 l._log.Output(4, s) 268 } 269 270 func (l *logger) logf(t LogType, format string, v ...interface{}) { 271 if l.level|LogLevel(t) != l.level { 272 return 273 } 274 275 err := l.rotate() 276 if err != nil { 277 fmt.Fprintf(os.Stderr, "%s\n", err.Error()) 278 return 279 } 280 281 logStr, logColor := LogTypeToString(t) 282 var s string 283 if l.highlighting { 284 s = "\033" + logColor + "m[" + logStr + "] " + fmt.Sprintf(format, v...) + "\033[0m" 285 } else { 286 s = "[" + logStr + "] " + fmt.Sprintf(format, v...) 287 } 288 l._log.Output(4, s) 289 } 290 291 func (l *logger) Fatal(v ...interface{}) { 292 l.log(LOG_FATAL, v...) 293 os.Exit(-1) 294 } 295 296 func (l *logger) Fatalf(format string, v ...interface{}) { 297 l.logf(LOG_FATAL, format, v...) 298 os.Exit(-1) 299 } 300 301 func (l *logger) Error(v ...interface{}) { 302 l.log(LOG_ERROR, v...) 303 } 304 305 func (l *logger) Errorf(format string, v ...interface{}) { 306 l.logf(LOG_ERROR, format, v...) 307 } 308 309 func (l *logger) Warning(v ...interface{}) { 310 l.log(LOG_WARNING, v...) 311 } 312 313 func (l *logger) Warningf(format string, v ...interface{}) { 314 l.logf(LOG_WARNING, format, v...) 315 } 316 317 func (l *logger) Debug(v ...interface{}) { 318 l.log(LOG_DEBUG, v...) 319 } 320 321 func (l *logger) Debugf(format string, v ...interface{}) { 322 l.logf(LOG_DEBUG, format, v...) 323 } 324 325 func (l *logger) Info(v ...interface{}) { 326 l.log(LOG_INFO, v...) 327 } 328 329 func (l *logger) Infof(format string, v ...interface{}) { 330 l.logf(LOG_INFO, format, v...) 331 } 332 333 func StringToLogLevel(level string) LogLevel { 334 switch level { 335 case "fatal": 336 return LOG_LEVEL_FATAL 337 case "error": 338 return LOG_LEVEL_ERROR 339 case "warn": 340 return LOG_LEVEL_WARN 341 case "warning": 342 return LOG_LEVEL_WARN 343 case "debug": 344 return LOG_LEVEL_DEBUG 345 case "info": 346 return LOG_LEVEL_INFO 347 } 348 return LOG_LEVEL_ALL 349 } 350 351 func LogTypeToString(t LogType) (string, string) { 352 switch t { 353 case LOG_FATAL: 354 return "fatal", "[0;31" 355 case LOG_ERROR: 356 return "error", "[0;31" 357 case LOG_WARNING: 358 return "warning", "[0;33" 359 case LOG_DEBUG: 360 return "debug", "[0;36" 361 case LOG_INFO: 362 return "info", "[0;37" 363 } 364 return "unknown", "[0;37" 365 } 366 367 func genDayTime(t time.Time) string { 368 return t.Format(FORMAT_TIME_DAY) 369 } 370 371 func genHourTime(t time.Time) string { 372 return t.Format(FORMAT_TIME_HOUR) 373 } 374 375 func New() *logger { 376 return Newlogger(os.Stdout, "") 377 } 378 379 func Newlogger(w io.Writer, prefix string) *logger { 380 return &logger{_log: log.New(w, prefix, LstdFlags), level: LOG_LEVEL_ALL, highlighting: true} 381 }