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.
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.
27 // These flags define which text to prefix to each log entry generated by the Logger.
28 // Bits are or'ed together to control what's printed.
29 // With the exception of the Lmsgprefix flag, there is no
30 // control over the order they appear (the order listed here)
31 // or the format they present (as described in the comments).
32 // The prefix is followed by a colon only when Llongfile or Lshortfile
34 // For example, flags Ldate | Ltime (or LstdFlags) produce,
35 // 2009/01/23 01:23:23 message
36 // while flags Ldate | Ltime | Lmicroseconds | Llongfile produce,
37 // 2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message
39 Ldate
= 1 << iota // the date in the local time zone: 2009/01/23
40 Ltime
// the time in the local time zone: 01:23:23
41 Lmicroseconds
// microsecond resolution: 01:23:23.123123. assumes Ltime.
42 Llongfile
// full file name and line number: /a/b/c/d.go:23
43 Lshortfile
// final file name element and line number: d.go:23. overrides Llongfile
44 LUTC
// if Ldate or Ltime is set, use UTC rather than the local time zone
45 Lmsgprefix
// move the "prefix" from the beginning of the line to before the message
46 LstdFlags
= Ldate | Ltime
// initial values for the standard logger
49 // A Logger represents an active logging object that generates lines of
50 // output to an io.Writer. Each logging operation makes a single call to
51 // the Writer's Write method. A Logger can be used simultaneously from
52 // multiple goroutines; it guarantees to serialize access to the Writer.
54 mu sync
.Mutex
// ensures atomic writes; protects the following fields
55 prefix
string // prefix on each line to identify the logger (but see Lmsgprefix)
56 flag
int // properties
57 out io
.Writer
// destination for output
58 buf
[]byte // for accumulating text to write
59 isDiscard
int32 // atomic boolean: whether out == io.Discard
62 // New creates a new Logger. The out variable sets the
63 // destination to which log data will be written.
64 // The prefix appears at the beginning of each generated log line, or
65 // after the log header if the Lmsgprefix flag is provided.
66 // The flag argument defines the logging properties.
67 func New(out io
.Writer
, prefix
string, flag
int) *Logger
{
68 l
:= &Logger
{out
: out
, prefix
: prefix
, flag
: flag
}
69 if out
== io
.Discard
{
75 // SetOutput sets the output destination for the logger.
76 func (l
*Logger
) SetOutput(w io
.Writer
) {
84 atomic
.StoreInt32(&l
.isDiscard
, isDiscard
)
87 var std
= New(os
.Stderr
, "", LstdFlags
)
89 // Default returns the standard logger used by the package-level output functions.
90 func Default() *Logger
{ return std
}
92 // Cheap integer to fixed-width decimal ASCII. Give a negative width to avoid zero-padding.
93 func itoa(buf
*[]byte, i
int, wid
int) {
94 // Assemble decimal in reverse order.
97 for i
>= 10 || wid
> 1 {
100 b
[bp
] = byte('0' + i
- q
*10)
105 b
[bp
] = byte('0' + i
)
106 *buf
= append(*buf
, b
[bp
:]...)
109 // formatHeader writes log header to buf in following order:
110 // * l.prefix (if it's not blank and Lmsgprefix is unset),
111 // * date and/or time (if corresponding flags are provided),
112 // * file and line number (if corresponding flags are provided),
113 // * l.prefix (if it's not blank and Lmsgprefix is set).
114 func (l
*Logger
) formatHeader(buf
*[]byte, t time
.Time
, file
string, line
int) {
115 if l
.flag
&Lmsgprefix
== 0 {
116 *buf
= append(*buf
, l
.prefix
...)
118 if l
.flag
&(Ldate|Ltime|Lmicroseconds
) != 0 {
119 if l
.flag
&LUTC
!= 0 {
122 if l
.flag
&Ldate
!= 0 {
123 year
, month
, day
:= t
.Date()
125 *buf
= append(*buf
, '/')
126 itoa(buf
, int(month
), 2)
127 *buf
= append(*buf
, '/')
129 *buf
= append(*buf
, ' ')
131 if l
.flag
&(Ltime|Lmicroseconds
) != 0 {
132 hour
, min
, sec
:= t
.Clock()
134 *buf
= append(*buf
, ':')
136 *buf
= append(*buf
, ':')
138 if l
.flag
&Lmicroseconds
!= 0 {
139 *buf
= append(*buf
, '.')
140 itoa(buf
, t
.Nanosecond()/1e3
, 6)
142 *buf
= append(*buf
, ' ')
145 if l
.flag
&(Lshortfile|Llongfile
) != 0 {
146 if l
.flag
&Lshortfile
!= 0 {
148 for i
:= len(file
) - 1; i
> 0; i
-- {
156 *buf
= append(*buf
, file
...)
157 *buf
= append(*buf
, ':')
159 *buf
= append(*buf
, ": "...)
161 if l
.flag
&Lmsgprefix
!= 0 {
162 *buf
= append(*buf
, l
.prefix
...)
166 // Output writes the output for a logging event. The string s contains
167 // the text to print after the prefix specified by the flags of the
168 // Logger. A newline is appended if the last character of s is not
169 // already a newline. Calldepth is used to recover the PC and is
170 // provided for generality, although at the moment on all pre-defined
171 // paths it will be 2.
172 func (l
*Logger
) Output(calldepth
int, s
string) error
{
173 now
:= time
.Now() // get this early.
178 if l
.flag
&(Lshortfile|Llongfile
) != 0 {
179 // Release lock while getting caller info - it's expensive.
182 _
, file
, line
, ok
= runtime
.Caller(calldepth
)
190 l
.formatHeader(&l
.buf
, now
, file
, line
)
191 l
.buf
= append(l
.buf
, s
...)
192 if len(s
) == 0 || s
[len(s
)-1] != '\n' {
193 l
.buf
= append(l
.buf
, '\n')
195 _
, err
:= l
.out
.Write(l
.buf
)
199 // Printf calls l.Output to print to the logger.
200 // Arguments are handled in the manner of fmt.Printf.
201 func (l
*Logger
) Printf(format
string, v
...any
) {
202 if atomic
.LoadInt32(&l
.isDiscard
) != 0 {
205 l
.Output(2, fmt
.Sprintf(format
, v
...))
208 // Print calls l.Output to print to the logger.
209 // Arguments are handled in the manner of fmt.Print.
210 func (l
*Logger
) Print(v
...any
) {
211 if atomic
.LoadInt32(&l
.isDiscard
) != 0 {
214 l
.Output(2, fmt
.Sprint(v
...))
217 // Println calls l.Output to print to the logger.
218 // Arguments are handled in the manner of fmt.Println.
219 func (l
*Logger
) Println(v
...any
) {
220 if atomic
.LoadInt32(&l
.isDiscard
) != 0 {
223 l
.Output(2, fmt
.Sprintln(v
...))
226 // Fatal is equivalent to l.Print() followed by a call to os.Exit(1).
227 func (l
*Logger
) Fatal(v
...any
) {
228 l
.Output(2, fmt
.Sprint(v
...))
232 // Fatalf is equivalent to l.Printf() followed by a call to os.Exit(1).
233 func (l
*Logger
) Fatalf(format
string, v
...any
) {
234 l
.Output(2, fmt
.Sprintf(format
, v
...))
238 // Fatalln is equivalent to l.Println() followed by a call to os.Exit(1).
239 func (l
*Logger
) Fatalln(v
...any
) {
240 l
.Output(2, fmt
.Sprintln(v
...))
244 // Panic is equivalent to l.Print() followed by a call to panic().
245 func (l
*Logger
) Panic(v
...any
) {
246 s
:= fmt
.Sprint(v
...)
251 // Panicf is equivalent to l.Printf() followed by a call to panic().
252 func (l
*Logger
) Panicf(format
string, v
...any
) {
253 s
:= fmt
.Sprintf(format
, v
...)
258 // Panicln is equivalent to l.Println() followed by a call to panic().
259 func (l
*Logger
) Panicln(v
...any
) {
260 s
:= fmt
.Sprintln(v
...)
265 // Flags returns the output flags for the logger.
266 // The flag bits are Ldate, Ltime, and so on.
267 func (l
*Logger
) Flags() int {
273 // SetFlags sets the output flags for the logger.
274 // The flag bits are Ldate, Ltime, and so on.
275 func (l
*Logger
) SetFlags(flag
int) {
281 // Prefix returns the output prefix for the logger.
282 func (l
*Logger
) Prefix() string {
288 // SetPrefix sets the output prefix for the logger.
289 func (l
*Logger
) SetPrefix(prefix
string) {
295 // Writer returns the output destination for the logger.
296 func (l
*Logger
) Writer() io
.Writer
{
302 // SetOutput sets the output destination for the standard logger.
303 func SetOutput(w io
.Writer
) {
307 // Flags returns the output flags for the standard logger.
308 // The flag bits are Ldate, Ltime, and so on.
313 // SetFlags sets the output flags for the standard logger.
314 // The flag bits are Ldate, Ltime, and so on.
315 func SetFlags(flag
int) {
319 // Prefix returns the output prefix for the standard logger.
320 func Prefix() string {
324 // SetPrefix sets the output prefix for the standard logger.
325 func SetPrefix(prefix
string) {
326 std
.SetPrefix(prefix
)
329 // Writer returns the output destination for the standard logger.
330 func Writer() io
.Writer
{
334 // These functions write to the standard logger.
336 // Print calls Output to print to the standard logger.
337 // Arguments are handled in the manner of fmt.Print.
338 func Print(v
...any
) {
339 if atomic
.LoadInt32(&std
.isDiscard
) != 0 {
342 std
.Output(2, fmt
.Sprint(v
...))
345 // Printf calls Output to print to the standard logger.
346 // Arguments are handled in the manner of fmt.Printf.
347 func Printf(format
string, v
...any
) {
348 if atomic
.LoadInt32(&std
.isDiscard
) != 0 {
351 std
.Output(2, fmt
.Sprintf(format
, v
...))
354 // Println calls Output to print to the standard logger.
355 // Arguments are handled in the manner of fmt.Println.
356 func Println(v
...any
) {
357 if atomic
.LoadInt32(&std
.isDiscard
) != 0 {
360 std
.Output(2, fmt
.Sprintln(v
...))
363 // Fatal is equivalent to Print() followed by a call to os.Exit(1).
364 func Fatal(v
...any
) {
365 std
.Output(2, fmt
.Sprint(v
...))
369 // Fatalf is equivalent to Printf() followed by a call to os.Exit(1).
370 func Fatalf(format
string, v
...any
) {
371 std
.Output(2, fmt
.Sprintf(format
, v
...))
375 // Fatalln is equivalent to Println() followed by a call to os.Exit(1).
376 func Fatalln(v
...any
) {
377 std
.Output(2, fmt
.Sprintln(v
...))
381 // Panic is equivalent to Print() followed by a call to panic().
382 func Panic(v
...any
) {
383 s
:= fmt
.Sprint(v
...)
388 // Panicf is equivalent to Printf() followed by a call to panic().
389 func Panicf(format
string, v
...any
) {
390 s
:= fmt
.Sprintf(format
, v
...)
395 // Panicln is equivalent to Println() followed by a call to panic().
396 func Panicln(v
...any
) {
397 s
:= fmt
.Sprintln(v
...)
402 // Output writes the output for a logging event. The string s contains
403 // the text to print after the prefix specified by the flags of the
404 // Logger. A newline is appended if the last character of s is not
405 // already a newline. Calldepth is the count of the number of
406 // frames to skip when computing the file name and line number
407 // if Llongfile or Lshortfile is set; a value of 1 will print the details
408 // for the caller of Output.
409 func Output(calldepth
int, s
string) error
{
410 return std
.Output(calldepth
+1, s
) // +1 for this frame.