github.com/c12o16h1/go/src@v0.0.0-20200114212001-5a151c0f00ed/log/log.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package log implements a simple logging package. It defines a type, Logger, 6 // with methods for formatting output. It also has a predefined 'standard' 7 // Logger accessible through helper functions Print[f|ln], Fatal[f|ln], and 8 // Panic[f|ln], which are easier to use than creating a Logger manually. 9 // That logger writes to standard error and prints the date and time 10 // of each logged message. 11 // Every log message is output on a separate line: if the message being 12 // printed does not end in a newline, the logger will add one. 13 // The Fatal functions call os.Exit(1) after writing the log message. 14 // The Panic functions call panic after writing the log message. 15 package log 16 17 import ( 18 "fmt" 19 "io" 20 "os" 21 "runtime" 22 "sync" 23 "time" 24 ) 25 26 // These flags define which text to prefix to each log entry generated by the Logger. 27 // Bits are or'ed together to control what's printed. 28 // With the exception of the Lmsgprefix flag, there is no 29 // control over the order they appear (the order listed here) 30 // or the format they present (as described in the comments). 31 // The prefix is followed by a colon only when Llongfile or Lshortfile 32 // is specified. 33 // For example, flags Ldate | Ltime (or LstdFlags) produce, 34 // 2009/01/23 01:23:23 message 35 // while flags Ldate | Ltime | Lmicroseconds | Llongfile produce, 36 // 2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message 37 const ( 38 Ldate = 1 << iota // the date in the local time zone: 2009/01/23 39 Ltime // the time in the local time zone: 01:23:23 40 Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime. 41 Llongfile // full file name and line number: /a/b/c/d.go:23 42 Lshortfile // final file name element and line number: d.go:23. overrides Llongfile 43 LUTC // if Ldate or Ltime is set, use UTC rather than the local time zone 44 Lmsgprefix // move the "prefix" from the beginning of the line to before the message 45 LstdFlags = Ldate | Ltime // initial values for the standard logger 46 ) 47 48 // A Logger represents an active logging object that generates lines of 49 // output to an io.Writer. Each logging operation makes a single call to 50 // the Writer's Write method. A Logger can be used simultaneously from 51 // multiple goroutines; it guarantees to serialize access to the Writer. 52 type Logger struct { 53 mu sync.Mutex // ensures atomic writes; protects the following fields 54 prefix string // prefix on each line to identify the logger (but see Lmsgprefix) 55 flag int // properties 56 out io.Writer // destination for output 57 buf []byte // for accumulating text to write 58 } 59 60 // New creates a new Logger. The out variable sets the 61 // destination to which log data will be written. 62 // The prefix appears at the beginning of each generated log line, or 63 // after the log header if the Lmsgprefix flag is provided. 64 // The flag argument defines the logging properties. 65 func New(out io.Writer, prefix string, flag int) *Logger { 66 return &Logger{out: out, prefix: prefix, flag: flag} 67 } 68 69 // SetOutput sets the output destination for the logger. 70 func (l *Logger) SetOutput(w io.Writer) { 71 l.mu.Lock() 72 defer l.mu.Unlock() 73 l.out = w 74 } 75 76 var std = New(os.Stderr, "", LstdFlags) 77 78 // Cheap integer to fixed-width decimal ASCII. Give a negative width to avoid zero-padding. 79 func itoa(buf *[]byte, i int, wid int) { 80 // Assemble decimal in reverse order. 81 var b [20]byte 82 bp := len(b) - 1 83 for i >= 10 || wid > 1 { 84 wid-- 85 q := i / 10 86 b[bp] = byte('0' + i - q*10) 87 bp-- 88 i = q 89 } 90 // i < 10 91 b[bp] = byte('0' + i) 92 *buf = append(*buf, b[bp:]...) 93 } 94 95 // formatHeader writes log header to buf in following order: 96 // * l.prefix (if it's not blank and Lmsgprefix is unset), 97 // * date and/or time (if corresponding flags are provided), 98 // * file and line number (if corresponding flags are provided), 99 // * l.prefix (if it's not blank and Lmsgprefix is set). 100 func (l *Logger) formatHeader(buf *[]byte, t time.Time, file string, line int) { 101 if l.flag&Lmsgprefix == 0 { 102 *buf = append(*buf, l.prefix...) 103 } 104 if l.flag&(Ldate|Ltime|Lmicroseconds) != 0 { 105 if l.flag&LUTC != 0 { 106 t = t.UTC() 107 } 108 if l.flag&Ldate != 0 { 109 year, month, day := t.Date() 110 itoa(buf, year, 4) 111 *buf = append(*buf, '/') 112 itoa(buf, int(month), 2) 113 *buf = append(*buf, '/') 114 itoa(buf, day, 2) 115 *buf = append(*buf, ' ') 116 } 117 if l.flag&(Ltime|Lmicroseconds) != 0 { 118 hour, min, sec := t.Clock() 119 itoa(buf, hour, 2) 120 *buf = append(*buf, ':') 121 itoa(buf, min, 2) 122 *buf = append(*buf, ':') 123 itoa(buf, sec, 2) 124 if l.flag&Lmicroseconds != 0 { 125 *buf = append(*buf, '.') 126 itoa(buf, t.Nanosecond()/1e3, 6) 127 } 128 *buf = append(*buf, ' ') 129 } 130 } 131 if l.flag&(Lshortfile|Llongfile) != 0 { 132 if l.flag&Lshortfile != 0 { 133 short := file 134 for i := len(file) - 1; i > 0; i-- { 135 if file[i] == '/' { 136 short = file[i+1:] 137 break 138 } 139 } 140 file = short 141 } 142 *buf = append(*buf, file...) 143 *buf = append(*buf, ':') 144 itoa(buf, line, -1) 145 *buf = append(*buf, ": "...) 146 } 147 if l.flag&Lmsgprefix != 0 { 148 *buf = append(*buf, l.prefix...) 149 } 150 } 151 152 // Output writes the output for a logging event. The string s contains 153 // the text to print after the prefix specified by the flags of the 154 // Logger. A newline is appended if the last character of s is not 155 // already a newline. Calldepth is used to recover the PC and is 156 // provided for generality, although at the moment on all pre-defined 157 // paths it will be 2. 158 func (l *Logger) Output(calldepth int, s string) error { 159 now := time.Now() // get this early. 160 var file string 161 var line int 162 l.mu.Lock() 163 defer l.mu.Unlock() 164 if l.flag&(Lshortfile|Llongfile) != 0 { 165 // Release lock while getting caller info - it's expensive. 166 l.mu.Unlock() 167 var ok bool 168 _, file, line, ok = runtime.Caller(calldepth) 169 if !ok { 170 file = "???" 171 line = 0 172 } 173 l.mu.Lock() 174 } 175 l.buf = l.buf[:0] 176 l.formatHeader(&l.buf, now, file, line) 177 l.buf = append(l.buf, s...) 178 if len(s) == 0 || s[len(s)-1] != '\n' { 179 l.buf = append(l.buf, '\n') 180 } 181 _, err := l.out.Write(l.buf) 182 return err 183 } 184 185 // Printf calls l.Output to print to the logger. 186 // Arguments are handled in the manner of fmt.Printf. 187 func (l *Logger) Printf(format string, v ...interface{}) { 188 l.Output(2, fmt.Sprintf(format, v...)) 189 } 190 191 // Print calls l.Output to print to the logger. 192 // Arguments are handled in the manner of fmt.Print. 193 func (l *Logger) Print(v ...interface{}) { l.Output(2, fmt.Sprint(v...)) } 194 195 // Println calls l.Output to print to the logger. 196 // Arguments are handled in the manner of fmt.Println. 197 func (l *Logger) Println(v ...interface{}) { l.Output(2, fmt.Sprintln(v...)) } 198 199 // Fatal is equivalent to l.Print() followed by a call to os.Exit(1). 200 func (l *Logger) Fatal(v ...interface{}) { 201 l.Output(2, fmt.Sprint(v...)) 202 os.Exit(1) 203 } 204 205 // Fatalf is equivalent to l.Printf() followed by a call to os.Exit(1). 206 func (l *Logger) Fatalf(format string, v ...interface{}) { 207 l.Output(2, fmt.Sprintf(format, v...)) 208 os.Exit(1) 209 } 210 211 // Fatalln is equivalent to l.Println() followed by a call to os.Exit(1). 212 func (l *Logger) Fatalln(v ...interface{}) { 213 l.Output(2, fmt.Sprintln(v...)) 214 os.Exit(1) 215 } 216 217 // Panic is equivalent to l.Print() followed by a call to panic(). 218 func (l *Logger) Panic(v ...interface{}) { 219 s := fmt.Sprint(v...) 220 l.Output(2, s) 221 panic(s) 222 } 223 224 // Panicf is equivalent to l.Printf() followed by a call to panic(). 225 func (l *Logger) Panicf(format string, v ...interface{}) { 226 s := fmt.Sprintf(format, v...) 227 l.Output(2, s) 228 panic(s) 229 } 230 231 // Panicln is equivalent to l.Println() followed by a call to panic(). 232 func (l *Logger) Panicln(v ...interface{}) { 233 s := fmt.Sprintln(v...) 234 l.Output(2, s) 235 panic(s) 236 } 237 238 // Flags returns the output flags for the logger. 239 // The flag bits are Ldate, Ltime, and so on. 240 func (l *Logger) Flags() int { 241 l.mu.Lock() 242 defer l.mu.Unlock() 243 return l.flag 244 } 245 246 // SetFlags sets the output flags for the logger. 247 // The flag bits are Ldate, Ltime, and so on. 248 func (l *Logger) SetFlags(flag int) { 249 l.mu.Lock() 250 defer l.mu.Unlock() 251 l.flag = flag 252 } 253 254 // Prefix returns the output prefix for the logger. 255 func (l *Logger) Prefix() string { 256 l.mu.Lock() 257 defer l.mu.Unlock() 258 return l.prefix 259 } 260 261 // SetPrefix sets the output prefix for the logger. 262 func (l *Logger) SetPrefix(prefix string) { 263 l.mu.Lock() 264 defer l.mu.Unlock() 265 l.prefix = prefix 266 } 267 268 // Writer returns the output destination for the logger. 269 func (l *Logger) Writer() io.Writer { 270 l.mu.Lock() 271 defer l.mu.Unlock() 272 return l.out 273 } 274 275 // SetOutput sets the output destination for the standard logger. 276 func SetOutput(w io.Writer) { 277 std.mu.Lock() 278 defer std.mu.Unlock() 279 std.out = w 280 } 281 282 // Flags returns the output flags for the standard logger. 283 // The flag bits are Ldate, Ltime, and so on. 284 func Flags() int { 285 return std.Flags() 286 } 287 288 // SetFlags sets the output flags for the standard logger. 289 // The flag bits are Ldate, Ltime, and so on. 290 func SetFlags(flag int) { 291 std.SetFlags(flag) 292 } 293 294 // Prefix returns the output prefix for the standard logger. 295 func Prefix() string { 296 return std.Prefix() 297 } 298 299 // SetPrefix sets the output prefix for the standard logger. 300 func SetPrefix(prefix string) { 301 std.SetPrefix(prefix) 302 } 303 304 // Writer returns the output destination for the standard logger. 305 func Writer() io.Writer { 306 return std.Writer() 307 } 308 309 // These functions write to the standard logger. 310 311 // Print calls Output to print to the standard logger. 312 // Arguments are handled in the manner of fmt.Print. 313 func Print(v ...interface{}) { 314 std.Output(2, fmt.Sprint(v...)) 315 } 316 317 // Printf calls Output to print to the standard logger. 318 // Arguments are handled in the manner of fmt.Printf. 319 func Printf(format string, v ...interface{}) { 320 std.Output(2, fmt.Sprintf(format, v...)) 321 } 322 323 // Println calls Output to print to the standard logger. 324 // Arguments are handled in the manner of fmt.Println. 325 func Println(v ...interface{}) { 326 std.Output(2, fmt.Sprintln(v...)) 327 } 328 329 // Fatal is equivalent to Print() followed by a call to os.Exit(1). 330 func Fatal(v ...interface{}) { 331 std.Output(2, fmt.Sprint(v...)) 332 os.Exit(1) 333 } 334 335 // Fatalf is equivalent to Printf() followed by a call to os.Exit(1). 336 func Fatalf(format string, v ...interface{}) { 337 std.Output(2, fmt.Sprintf(format, v...)) 338 os.Exit(1) 339 } 340 341 // Fatalln is equivalent to Println() followed by a call to os.Exit(1). 342 func Fatalln(v ...interface{}) { 343 std.Output(2, fmt.Sprintln(v...)) 344 os.Exit(1) 345 } 346 347 // Panic is equivalent to Print() followed by a call to panic(). 348 func Panic(v ...interface{}) { 349 s := fmt.Sprint(v...) 350 std.Output(2, s) 351 panic(s) 352 } 353 354 // Panicf is equivalent to Printf() followed by a call to panic(). 355 func Panicf(format string, v ...interface{}) { 356 s := fmt.Sprintf(format, v...) 357 std.Output(2, s) 358 panic(s) 359 } 360 361 // Panicln is equivalent to Println() followed by a call to panic(). 362 func Panicln(v ...interface{}) { 363 s := fmt.Sprintln(v...) 364 std.Output(2, s) 365 panic(s) 366 } 367 368 // Output writes the output for a logging event. The string s contains 369 // the text to print after the prefix specified by the flags of the 370 // Logger. A newline is appended if the last character of s is not 371 // already a newline. Calldepth is the count of the number of 372 // frames to skip when computing the file name and line number 373 // if Llongfile or Lshortfile is set; a value of 1 will print the details 374 // for the caller of Output. 375 func Output(calldepth int, s string) error { 376 return std.Output(calldepth+1, s) // +1 for this frame. 377 }