github.com/woremacx/kocha@v0.7.1-0.20150731103243-a5889322afc9/log/logger.go (about) 1 package log 2 3 import ( 4 "bytes" 5 "io" 6 "os" 7 "sort" 8 "sync" 9 "sync/atomic" 10 11 "github.com/mattn/go-colorable" 12 "github.com/mattn/go-isatty" 13 ) 14 15 // Logger is the interface that logger. 16 type Logger interface { 17 // Debug calls Logger.Output to print to the logger with DEBUG level. 18 // Arguments are handled in the manner of fmt.Print. 19 // If the current log level is upper than DEBUG, it won't be the output. 20 Debug(v ...interface{}) 21 22 // Debugf calls Logger.Output to print to the logger with DEBUG level. 23 // Arguments are handled in the manner of fmt.Printf. 24 // If the current log level is upper than DEBUG, it won't be the output. 25 Debugf(format string, v ...interface{}) 26 27 // Debugln calls Logger.Output to print to the logger with DEBUG level. 28 // Arguments are handled in the manner of fmt.Println. 29 // If the current log level is upper than DEBUG, it won't be the output. 30 Debugln(v ...interface{}) 31 32 // Info calls Logger.Output to print to the logger with INFO level. 33 // Arguments are handled in the manner of fmt.Print. 34 // If the current log level is upper than INFO, it won't be the output. 35 Info(v ...interface{}) 36 37 // Infof calls Logger.Output to print to the logger with INFO level. 38 // Arguments are handled in the manner of fmt.Printf. 39 // If the current log level is upper than INFO, it won't be the output. 40 Infof(format string, v ...interface{}) 41 42 // Infoln calls Logger.Output to print to the logger with INFO level. 43 // Arguments are handled in the manner of fmt.Println. 44 // If the current log level is upper than INFO, it won't be the output. 45 Infoln(v ...interface{}) 46 47 // Warn calls Logger.Output to print to the logger with WARN level. 48 // Arguments are handled in the manner of fmt.Print. 49 // If the current log level is upper than WARN, it won't be the output. 50 Warn(v ...interface{}) 51 52 // Warnf calls Logger.Output to print to the logger with WARN level. 53 // Arguments are handled in the manner of fmt.Printf. 54 // If the current log level is upper than WARN, it won't be the output. 55 Warnf(format string, v ...interface{}) 56 57 // Warnln calls Logger.Output to print to the logger with WARN level. 58 // Arguments are handled in the manner of fmt.Println. 59 // If the current log level is upper than WARN, it won't be the output. 60 Warnln(v ...interface{}) 61 62 // Error calls Logger.Output to print to the logger with ERROR level. 63 // Arguments are handled in the manner of fmt.Print. 64 // If the current log level is upper than ERROR, it won't be the output. 65 Error(v ...interface{}) 66 67 // Errorf calls Logger.Output to print to the logger with ERROR level. 68 // Arguments are handled in the manner of fmt.Printf. 69 // If the current log level is upper than ERROR, it won't be the output. 70 Errorf(format string, v ...interface{}) 71 72 // Errorln calls Logger.Output to print to the logger with ERROR level. 73 // Arguments are handled in the manner of fmt.Println. 74 // If the current log level is upper than ERROR, it won't be the output. 75 Errorln(v ...interface{}) 76 77 // Fatal calls Logger.Output to print to the logger with FATAL level. 78 // Arguments are handled in the manner of fmt.Print. 79 // Also calls os.Exit(1) after the output. 80 Fatal(v ...interface{}) 81 82 // Fatalf calls Logger.Output to print to the logger with FATAL level. 83 // Arguments are handled in the manner of fmt.Printf. 84 // Also calls os.Exit(1) after the output. 85 Fatalf(format string, v ...interface{}) 86 87 // Fatalln calls Logger.Output to print to the logger with FATAL level. 88 // Arguments are handled in the manner of fmt.Println. 89 // Also calls os.Exit(1) after the output. 90 Fatalln(v ...interface{}) 91 92 // Panic calls Logger.Output to print to the logger with PANIC level. 93 // Arguments are handled in the manner of fmt.Print. 94 // Also calls panic() after the output. 95 Panic(v ...interface{}) 96 97 // Panicf calls Logger.Output to print to the logger with PANIC level. 98 // Arguments are handled in the manner of fmt.Printf. 99 // Also calls panic() after the output. 100 Panicf(format string, v ...interface{}) 101 102 // Panicln calls Logger.Output to print to the logger with PANIC level. 103 // Arguments are handled in the manner of fmt.Println. 104 // Also calls panic() after the output. 105 Panicln(v ...interface{}) 106 107 // Print calls Logger.Output to print to the logger with NONE level. 108 // Arguments are handled in the manner of fmt.Print. 109 Print(v ...interface{}) 110 111 // Printf calls Logger.Output to print to the logger with NONE level. 112 // Arguments are handled in the manner of fmt.Printf. 113 Printf(format string, v ...interface{}) 114 115 // Println calls Logger.Output to print to the logger with NONE level. 116 // Arguments are handled in the manner of fmt.Println. 117 Println(v ...interface{}) 118 119 // Output writes the output for a logging event with the given level. 120 // The given message will be format by Formatter. Also a newline is appended 121 // to the message before the output. 122 Output(level Level, message string) 123 124 // With returns a new Logger with fields. 125 With(fields Fields) Logger 126 127 // Level returns the current log level. 128 Level() Level 129 130 // SetLevel sets the log level. 131 SetLevel(level Level) 132 } 133 134 // New creates a new Logger. 135 func New(out io.Writer, formatter Formatter, level Level) Logger { 136 l := &logger{ 137 out: out, 138 formatter: formatter, 139 formatFuncs: plainFormats, 140 level: level, 141 } 142 if w, ok := out.(*os.File); ok && isatty.IsTerminal(w.Fd()) { 143 switch w { 144 case os.Stdout: 145 l.out = colorable.NewColorableStdout() 146 l.formatFuncs = coloredFormats 147 case os.Stderr: 148 l.out = colorable.NewColorableStderr() 149 l.formatFuncs = coloredFormats 150 } 151 } 152 return l 153 } 154 155 // logger implements the Logger interface. 156 type logger struct { 157 out io.Writer 158 formatter Formatter 159 formatFuncs [7]formatFunc 160 level Level 161 fields Fields 162 buf bytes.Buffer 163 mu sync.Mutex 164 } 165 166 func (l *logger) Debug(v ...interface{}) { 167 if l.Level() <= DEBUG { 168 newEntryLogger(l).Debug(v...) 169 } 170 } 171 172 func (l *logger) Debugf(format string, v ...interface{}) { 173 if l.Level() <= DEBUG { 174 newEntryLogger(l).Debugf(format, v...) 175 } 176 } 177 178 func (l *logger) Debugln(v ...interface{}) { 179 if l.Level() <= DEBUG { 180 newEntryLogger(l).Debugln(v...) 181 } 182 } 183 184 func (l *logger) Info(v ...interface{}) { 185 if l.Level() <= INFO { 186 newEntryLogger(l).Info(v...) 187 } 188 } 189 190 func (l *logger) Infof(format string, v ...interface{}) { 191 if l.Level() <= INFO { 192 newEntryLogger(l).Infof(format, v...) 193 } 194 } 195 196 func (l *logger) Infoln(v ...interface{}) { 197 if l.Level() <= INFO { 198 newEntryLogger(l).Infoln(v...) 199 } 200 } 201 202 func (l *logger) Warn(v ...interface{}) { 203 if l.Level() <= WARN { 204 newEntryLogger(l).Warn(v...) 205 } 206 } 207 208 func (l *logger) Warnf(format string, v ...interface{}) { 209 if l.Level() <= WARN { 210 newEntryLogger(l).Warnf(format, v...) 211 } 212 } 213 214 func (l *logger) Warnln(v ...interface{}) { 215 if l.Level() <= WARN { 216 newEntryLogger(l).Warnln(v...) 217 } 218 } 219 220 func (l *logger) Error(v ...interface{}) { 221 if l.Level() <= ERROR { 222 newEntryLogger(l).Error(v...) 223 } 224 } 225 226 func (l *logger) Errorf(format string, v ...interface{}) { 227 if l.Level() <= ERROR { 228 newEntryLogger(l).Errorf(format, v...) 229 } 230 } 231 232 func (l *logger) Errorln(v ...interface{}) { 233 if l.Level() <= ERROR { 234 newEntryLogger(l).Errorln(v...) 235 } 236 } 237 238 func (l *logger) Fatal(v ...interface{}) { 239 newEntryLogger(l).Fatal(v...) 240 } 241 242 func (l *logger) Fatalf(format string, v ...interface{}) { 243 newEntryLogger(l).Fatalf(format, v...) 244 } 245 246 func (l *logger) Fatalln(v ...interface{}) { 247 newEntryLogger(l).Fatalln(v...) 248 } 249 250 func (l *logger) Panic(v ...interface{}) { 251 newEntryLogger(l).Panic(v...) 252 } 253 254 func (l *logger) Panicf(format string, v ...interface{}) { 255 newEntryLogger(l).Panicf(format, v...) 256 } 257 258 func (l *logger) Panicln(v ...interface{}) { 259 newEntryLogger(l).Panicln(v...) 260 } 261 262 func (l *logger) Print(v ...interface{}) { 263 newEntryLogger(l).Print(v...) 264 } 265 266 func (l *logger) Printf(format string, v ...interface{}) { 267 newEntryLogger(l).Printf(format, v...) 268 } 269 270 func (l *logger) Println(v ...interface{}) { 271 newEntryLogger(l).Println(v...) 272 } 273 274 func (l *logger) Output(level Level, message string) { 275 newEntryLogger(l).Output(level, message) 276 } 277 278 func (l *logger) With(fields Fields) Logger { 279 return newEntryLogger(l).With(fields) 280 } 281 282 func (l *logger) Level() Level { 283 return Level(atomic.LoadUint32((*uint32)(&l.level))) 284 } 285 286 func (l *logger) SetLevel(level Level) { 287 atomic.StoreUint32((*uint32)(&l.level), uint32(level)) 288 } 289 290 // Level represents a log level. 291 type Level uint32 292 293 // The log levels. 294 const ( 295 NONE Level = iota 296 DEBUG 297 INFO 298 WARN 299 ERROR 300 FATAL 301 PANIC 302 ) 303 304 type formatFunc func(f Formatter, w io.Writer, entry *Entry) error 305 306 func makeFormat(esc string) formatFunc { 307 return func(f Formatter, w io.Writer, entry *Entry) error { 308 io.WriteString(w, esc) 309 err := f.Format(w, entry) 310 io.WriteString(w, "\x1b[0m") 311 return err 312 } 313 } 314 315 var coloredFormats = [...]formatFunc{ 316 Formatter.Format, // NONE 317 Formatter.Format, // DEBUG 318 Formatter.Format, // INFO 319 makeFormat("\x1b[33m"), // WARN 320 makeFormat("\x1b[31m"), // ERROR 321 makeFormat("\x1b[31m"), // FATAL 322 makeFormat("\x1b[31m"), // PANIC 323 } 324 325 var plainFormats = [...]formatFunc{ 326 Formatter.Format, // NONE 327 Formatter.Format, // DEBUG 328 Formatter.Format, // INFO 329 Formatter.Format, // WARN 330 Formatter.Format, // ERROR 331 Formatter.Format, // FATAL 332 Formatter.Format, // PANIC 333 } 334 335 // Fields represents the key-value pairs in a log Entry. 336 type Fields map[string]interface{} 337 338 // Get returns a value associated with the given key. 339 func (f Fields) Get(key string) interface{} { 340 return f[key] 341 } 342 343 // OrderedKeys returns the keys of f that sorted in increasing order. 344 // This is used if you need the consistent map iteration order. 345 // See also http://golang.org/doc/go1.3#map 346 func (f Fields) OrderedKeys() (keys []string) { 347 for k := range f { 348 keys = append(keys, k) 349 } 350 sort.Strings(keys) 351 return keys 352 }