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