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

View as plain text