Source file
src/log/log.go
Documentation: log
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package log
16
17 import (
18 "fmt"
19 "io"
20 "os"
21 "runtime"
22 "sync"
23 "sync/atomic"
24 "time"
25 )
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 const (
42 Ldate = 1 << iota
43 Ltime
44 Lmicroseconds
45 Llongfile
46 Lshortfile
47 LUTC
48 Lmsgprefix
49 LstdFlags = Ldate | Ltime
50 )
51
52
53
54
55
56 type Logger struct {
57 mu sync.Mutex
58 prefix string
59 flag int
60 out io.Writer
61 buf []byte
62 isDiscard int32
63 }
64
65
66
67
68
69
70 func New(out io.Writer, prefix string, flag int) *Logger {
71 l := &Logger{out: out, prefix: prefix, flag: flag}
72 if out == io.Discard {
73 l.isDiscard = 1
74 }
75 return l
76 }
77
78
79 func (l *Logger) SetOutput(w io.Writer) {
80 l.mu.Lock()
81 defer l.mu.Unlock()
82 l.out = w
83 isDiscard := int32(0)
84 if w == io.Discard {
85 isDiscard = 1
86 }
87 atomic.StoreInt32(&l.isDiscard, isDiscard)
88 }
89
90 var std = New(os.Stderr, "", LstdFlags)
91
92
93 func Default() *Logger { return std }
94
95
96 func itoa(buf *[]byte, i int, wid int) {
97
98 var b [20]byte
99 bp := len(b) - 1
100 for i >= 10 || wid > 1 {
101 wid--
102 q := i / 10
103 b[bp] = byte('0' + i - q*10)
104 bp--
105 i = q
106 }
107
108 b[bp] = byte('0' + i)
109 *buf = append(*buf, b[bp:]...)
110 }
111
112
113
114
115
116
117 func (l *Logger) formatHeader(buf *[]byte, t time.Time, file string, line int) {
118 if l.flag&Lmsgprefix == 0 {
119 *buf = append(*buf, l.prefix...)
120 }
121 if l.flag&(Ldate|Ltime|Lmicroseconds) != 0 {
122 if l.flag&LUTC != 0 {
123 t = t.UTC()
124 }
125 if l.flag&Ldate != 0 {
126 year, month, day := t.Date()
127 itoa(buf, year, 4)
128 *buf = append(*buf, '/')
129 itoa(buf, int(month), 2)
130 *buf = append(*buf, '/')
131 itoa(buf, day, 2)
132 *buf = append(*buf, ' ')
133 }
134 if l.flag&(Ltime|Lmicroseconds) != 0 {
135 hour, min, sec := t.Clock()
136 itoa(buf, hour, 2)
137 *buf = append(*buf, ':')
138 itoa(buf, min, 2)
139 *buf = append(*buf, ':')
140 itoa(buf, sec, 2)
141 if l.flag&Lmicroseconds != 0 {
142 *buf = append(*buf, '.')
143 itoa(buf, t.Nanosecond()/1e3, 6)
144 }
145 *buf = append(*buf, ' ')
146 }
147 }
148 if l.flag&(Lshortfile|Llongfile) != 0 {
149 if l.flag&Lshortfile != 0 {
150 short := file
151 for i := len(file) - 1; i > 0; i-- {
152 if file[i] == '/' {
153 short = file[i+1:]
154 break
155 }
156 }
157 file = short
158 }
159 *buf = append(*buf, file...)
160 *buf = append(*buf, ':')
161 itoa(buf, line, -1)
162 *buf = append(*buf, ": "...)
163 }
164 if l.flag&Lmsgprefix != 0 {
165 *buf = append(*buf, l.prefix...)
166 }
167 }
168
169
170
171
172
173
174
175 func (l *Logger) Output(calldepth int, s string) error {
176 now := time.Now()
177 var file string
178 var line int
179 l.mu.Lock()
180 defer l.mu.Unlock()
181 if l.flag&(Lshortfile|Llongfile) != 0 {
182
183 l.mu.Unlock()
184 var ok bool
185 _, file, line, ok = runtime.Caller(calldepth)
186 if !ok {
187 file = "???"
188 line = 0
189 }
190 l.mu.Lock()
191 }
192 l.buf = l.buf[:0]
193 l.formatHeader(&l.buf, now, file, line)
194 l.buf = append(l.buf, s...)
195 if len(s) == 0 || s[len(s)-1] != '\n' {
196 l.buf = append(l.buf, '\n')
197 }
198 _, err := l.out.Write(l.buf)
199 return err
200 }
201
202
203
204 func (l *Logger) Printf(format string, v ...any) {
205 if atomic.LoadInt32(&l.isDiscard) != 0 {
206 return
207 }
208 l.Output(2, fmt.Sprintf(format, v...))
209 }
210
211
212
213 func (l *Logger) Print(v ...any) {
214 if atomic.LoadInt32(&l.isDiscard) != 0 {
215 return
216 }
217 l.Output(2, fmt.Sprint(v...))
218 }
219
220
221
222 func (l *Logger) Println(v ...any) {
223 if atomic.LoadInt32(&l.isDiscard) != 0 {
224 return
225 }
226 l.Output(2, fmt.Sprintln(v...))
227 }
228
229
230 func (l *Logger) Fatal(v ...any) {
231 l.Output(2, fmt.Sprint(v...))
232 os.Exit(1)
233 }
234
235
236 func (l *Logger) Fatalf(format string, v ...any) {
237 l.Output(2, fmt.Sprintf(format, v...))
238 os.Exit(1)
239 }
240
241
242 func (l *Logger) Fatalln(v ...any) {
243 l.Output(2, fmt.Sprintln(v...))
244 os.Exit(1)
245 }
246
247
248 func (l *Logger) Panic(v ...any) {
249 s := fmt.Sprint(v...)
250 l.Output(2, s)
251 panic(s)
252 }
253
254
255 func (l *Logger) Panicf(format string, v ...any) {
256 s := fmt.Sprintf(format, v...)
257 l.Output(2, s)
258 panic(s)
259 }
260
261
262 func (l *Logger) Panicln(v ...any) {
263 s := fmt.Sprintln(v...)
264 l.Output(2, s)
265 panic(s)
266 }
267
268
269
270 func (l *Logger) Flags() int {
271 l.mu.Lock()
272 defer l.mu.Unlock()
273 return l.flag
274 }
275
276
277
278 func (l *Logger) SetFlags(flag int) {
279 l.mu.Lock()
280 defer l.mu.Unlock()
281 l.flag = flag
282 }
283
284
285 func (l *Logger) Prefix() string {
286 l.mu.Lock()
287 defer l.mu.Unlock()
288 return l.prefix
289 }
290
291
292 func (l *Logger) SetPrefix(prefix string) {
293 l.mu.Lock()
294 defer l.mu.Unlock()
295 l.prefix = prefix
296 }
297
298
299 func (l *Logger) Writer() io.Writer {
300 l.mu.Lock()
301 defer l.mu.Unlock()
302 return l.out
303 }
304
305
306 func SetOutput(w io.Writer) {
307 std.SetOutput(w)
308 }
309
310
311
312 func Flags() int {
313 return std.Flags()
314 }
315
316
317
318 func SetFlags(flag int) {
319 std.SetFlags(flag)
320 }
321
322
323 func Prefix() string {
324 return std.Prefix()
325 }
326
327
328 func SetPrefix(prefix string) {
329 std.SetPrefix(prefix)
330 }
331
332
333 func Writer() io.Writer {
334 return std.Writer()
335 }
336
337
338
339
340
341 func Print(v ...any) {
342 if atomic.LoadInt32(&std.isDiscard) != 0 {
343 return
344 }
345 std.Output(2, fmt.Sprint(v...))
346 }
347
348
349
350 func Printf(format string, v ...any) {
351 if atomic.LoadInt32(&std.isDiscard) != 0 {
352 return
353 }
354 std.Output(2, fmt.Sprintf(format, v...))
355 }
356
357
358
359 func Println(v ...any) {
360 if atomic.LoadInt32(&std.isDiscard) != 0 {
361 return
362 }
363 std.Output(2, fmt.Sprintln(v...))
364 }
365
366
367 func Fatal(v ...any) {
368 std.Output(2, fmt.Sprint(v...))
369 os.Exit(1)
370 }
371
372
373 func Fatalf(format string, v ...any) {
374 std.Output(2, fmt.Sprintf(format, v...))
375 os.Exit(1)
376 }
377
378
379 func Fatalln(v ...any) {
380 std.Output(2, fmt.Sprintln(v...))
381 os.Exit(1)
382 }
383
384
385 func Panic(v ...any) {
386 s := fmt.Sprint(v...)
387 std.Output(2, s)
388 panic(s)
389 }
390
391
392 func Panicf(format string, v ...any) {
393 s := fmt.Sprintf(format, v...)
394 std.Output(2, s)
395 panic(s)
396 }
397
398
399 func Panicln(v ...any) {
400 s := fmt.Sprintln(v...)
401 std.Output(2, s)
402 panic(s)
403 }
404
405
406
407
408
409
410
411
412 func Output(calldepth int, s string) error {
413 return std.Output(calldepth+1, s)
414 }
415
View as plain text