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