Source file src/pkg/log/log.go
1
2
3
4
5
6
7
8
9
10
11
12
13 package log
14
15 import (
16 "fmt"
17 "io"
18 "os"
19 "runtime"
20 "sync"
21 "time"
22 )
23
24
25 const (
26
27
28
29
30 Ldate = 1 << iota
31 Ltime
32 Lmicroseconds
33 Llongfile
34 Lshortfile
35 LstdFlags = Ldate | Ltime
36 )
37
38
39
40
41
42 type Logger struct {
43 mu sync.Mutex
44 prefix string
45 flag int
46 out io.Writer
47 buf []byte
48 }
49
50
51
52
53
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
61
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
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
125
126
127
128
129
130 func (l *Logger) Output(calldepth int, s string) error {
131 now := time.Now()
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
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
158
159 func (l *Logger) Printf(format string, v ...interface{}) {
160 l.Output(2, fmt.Sprintf(format, v...))
161 }
162
163
164
165 func (l *Logger) Print(v ...interface{}) { l.Output(2, fmt.Sprint(v...)) }
166
167
168
169 func (l *Logger) Println(v ...interface{}) { l.Output(2, fmt.Sprintln(v...)) }
170
171
172 func (l *Logger) Fatal(v ...interface{}) {
173 l.Output(2, fmt.Sprint(v...))
174 os.Exit(1)
175 }
176
177
178 func (l *Logger) Fatalf(format string, v ...interface{}) {
179 l.Output(2, fmt.Sprintf(format, v...))
180 os.Exit(1)
181 }
182
183
184 func (l *Logger) Fatalln(v ...interface{}) {
185 l.Output(2, fmt.Sprintln(v...))
186 os.Exit(1)
187 }
188
189
190 func (l *Logger) Panic(v ...interface{}) {
191 s := fmt.Sprint(v...)
192 l.Output(2, s)
193 panic(s)
194 }
195
196
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
204 func (l *Logger) Panicln(v ...interface{}) {
205 s := fmt.Sprintln(v...)
206 l.Output(2, s)
207 panic(s)
208 }
209
210
211 func (l *Logger) Flags() int {
212 l.mu.Lock()
213 defer l.mu.Unlock()
214 return l.flag
215 }
216
217
218 func (l *Logger) SetFlags(flag int) {
219 l.mu.Lock()
220 defer l.mu.Unlock()
221 l.flag = flag
222 }
223
224
225 func (l *Logger) Prefix() string {
226 l.mu.Lock()
227 defer l.mu.Unlock()
228 return l.prefix
229 }
230
231
232 func (l *Logger) SetPrefix(prefix string) {
233 l.mu.Lock()
234 defer l.mu.Unlock()
235 l.prefix = prefix
236 }
237
238
239 func SetOutput(w io.Writer) {
240 std.mu.Lock()
241 defer std.mu.Unlock()
242 std.out = w
243 }
244
245
246 func Flags() int {
247 return std.Flags()
248 }
249
250
251 func SetFlags(flag int) {
252 std.SetFlags(flag)
253 }
254
255
256 func Prefix() string {
257 return std.Prefix()
258 }
259
260
261 func SetPrefix(prefix string) {
262 std.SetPrefix(prefix)
263 }
264
265
266
267
268
269 func Print(v ...interface{}) {
270 std.Output(2, fmt.Sprint(v...))
271 }
272
273
274
275 func Printf(format string, v ...interface{}) {
276 std.Output(2, fmt.Sprintf(format, v...))
277 }
278
279
280
281 func Println(v ...interface{}) {
282 std.Output(2, fmt.Sprintln(v...))
283 }
284
285
286 func Fatal(v ...interface{}) {
287 std.Output(2, fmt.Sprint(v...))
288 os.Exit(1)
289 }
290
291
292 func Fatalf(format string, v ...interface{}) {
293 std.Output(2, fmt.Sprintf(format, v...))
294 os.Exit(1)
295 }
296
297
298 func Fatalln(v ...interface{}) {
299 std.Output(2, fmt.Sprintln(v...))
300 os.Exit(1)
301 }
302
303
304 func Panic(v ...interface{}) {
305 s := fmt.Sprint(v...)
306 std.Output(2, s)
307 panic(s)
308 }
309
310
311 func Panicf(format string, v ...interface{}) {
312 s := fmt.Sprintf(format, v...)
313 std.Output(2, s)
314 panic(s)
315 }
316
317
318 func Panicln(v ...interface{}) {
319 s := fmt.Sprintln(v...)
320 std.Output(2, s)
321 panic(s)
322 }
View as plain text