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