github.com/c12o16h1/go/src@v0.0.0-20200114212001-5a151c0f00ed/log/log.go (about)

     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  // Cheap integer to fixed-width decimal ASCII. Give a negative width to avoid zero-padding.
    79  func itoa(buf *[]byte, i int, wid int) {
    80  	// Assemble decimal in reverse order.
    81  	var b [20]byte
    82  	bp := len(b) - 1
    83  	for i >= 10 || wid > 1 {
    84  		wid--
    85  		q := i / 10
    86  		b[bp] = byte('0' + i - q*10)
    87  		bp--
    88  		i = q
    89  	}
    90  	// i < 10
    91  	b[bp] = byte('0' + i)
    92  	*buf = append(*buf, b[bp:]...)
    93  }
    94  
    95  // formatHeader writes log header to buf in following order:
    96  //   * l.prefix (if it's not blank and Lmsgprefix is unset),
    97  //   * date and/or time (if corresponding flags are provided),
    98  //   * file and line number (if corresponding flags are provided),
    99  //   * l.prefix (if it's not blank and Lmsgprefix is set).
   100  func (l *Logger) formatHeader(buf *[]byte, t time.Time, file string, line int) {
   101  	if l.flag&Lmsgprefix == 0 {
   102  		*buf = append(*buf, l.prefix...)
   103  	}
   104  	if l.flag&(Ldate|Ltime|Lmicroseconds) != 0 {
   105  		if l.flag&LUTC != 0 {
   106  			t = t.UTC()
   107  		}
   108  		if l.flag&Ldate != 0 {
   109  			year, month, day := t.Date()
   110  			itoa(buf, year, 4)
   111  			*buf = append(*buf, '/')
   112  			itoa(buf, int(month), 2)
   113  			*buf = append(*buf, '/')
   114  			itoa(buf, day, 2)
   115  			*buf = append(*buf, ' ')
   116  		}
   117  		if l.flag&(Ltime|Lmicroseconds) != 0 {
   118  			hour, min, sec := t.Clock()
   119  			itoa(buf, hour, 2)
   120  			*buf = append(*buf, ':')
   121  			itoa(buf, min, 2)
   122  			*buf = append(*buf, ':')
   123  			itoa(buf, sec, 2)
   124  			if l.flag&Lmicroseconds != 0 {
   125  				*buf = append(*buf, '.')
   126  				itoa(buf, t.Nanosecond()/1e3, 6)
   127  			}
   128  			*buf = append(*buf, ' ')
   129  		}
   130  	}
   131  	if l.flag&(Lshortfile|Llongfile) != 0 {
   132  		if l.flag&Lshortfile != 0 {
   133  			short := file
   134  			for i := len(file) - 1; i > 0; i-- {
   135  				if file[i] == '/' {
   136  					short = file[i+1:]
   137  					break
   138  				}
   139  			}
   140  			file = short
   141  		}
   142  		*buf = append(*buf, file...)
   143  		*buf = append(*buf, ':')
   144  		itoa(buf, line, -1)
   145  		*buf = append(*buf, ": "...)
   146  	}
   147  	if l.flag&Lmsgprefix != 0 {
   148  		*buf = append(*buf, l.prefix...)
   149  	}
   150  }
   151  
   152  // Output writes the output for a logging event. The string s contains
   153  // the text to print after the prefix specified by the flags of the
   154  // Logger. A newline is appended if the last character of s is not
   155  // already a newline. Calldepth is used to recover the PC and is
   156  // provided for generality, although at the moment on all pre-defined
   157  // paths it will be 2.
   158  func (l *Logger) Output(calldepth int, s string) error {
   159  	now := time.Now() // get this early.
   160  	var file string
   161  	var line int
   162  	l.mu.Lock()
   163  	defer l.mu.Unlock()
   164  	if l.flag&(Lshortfile|Llongfile) != 0 {
   165  		// Release lock while getting caller info - it's expensive.
   166  		l.mu.Unlock()
   167  		var ok bool
   168  		_, file, line, ok = runtime.Caller(calldepth)
   169  		if !ok {
   170  			file = "???"
   171  			line = 0
   172  		}
   173  		l.mu.Lock()
   174  	}
   175  	l.buf = l.buf[:0]
   176  	l.formatHeader(&l.buf, now, file, line)
   177  	l.buf = append(l.buf, s...)
   178  	if len(s) == 0 || s[len(s)-1] != '\n' {
   179  		l.buf = append(l.buf, '\n')
   180  	}
   181  	_, err := l.out.Write(l.buf)
   182  	return err
   183  }
   184  
   185  // Printf calls l.Output to print to the logger.
   186  // Arguments are handled in the manner of fmt.Printf.
   187  func (l *Logger) Printf(format string, v ...interface{}) {
   188  	l.Output(2, fmt.Sprintf(format, v...))
   189  }
   190  
   191  // Print calls l.Output to print to the logger.
   192  // Arguments are handled in the manner of fmt.Print.
   193  func (l *Logger) Print(v ...interface{}) { l.Output(2, fmt.Sprint(v...)) }
   194  
   195  // Println calls l.Output to print to the logger.
   196  // Arguments are handled in the manner of fmt.Println.
   197  func (l *Logger) Println(v ...interface{}) { l.Output(2, fmt.Sprintln(v...)) }
   198  
   199  // Fatal is equivalent to l.Print() followed by a call to os.Exit(1).
   200  func (l *Logger) Fatal(v ...interface{}) {
   201  	l.Output(2, fmt.Sprint(v...))
   202  	os.Exit(1)
   203  }
   204  
   205  // Fatalf is equivalent to l.Printf() followed by a call to os.Exit(1).
   206  func (l *Logger) Fatalf(format string, v ...interface{}) {
   207  	l.Output(2, fmt.Sprintf(format, v...))
   208  	os.Exit(1)
   209  }
   210  
   211  // Fatalln is equivalent to l.Println() followed by a call to os.Exit(1).
   212  func (l *Logger) Fatalln(v ...interface{}) {
   213  	l.Output(2, fmt.Sprintln(v...))
   214  	os.Exit(1)
   215  }
   216  
   217  // Panic is equivalent to l.Print() followed by a call to panic().
   218  func (l *Logger) Panic(v ...interface{}) {
   219  	s := fmt.Sprint(v...)
   220  	l.Output(2, s)
   221  	panic(s)
   222  }
   223  
   224  // Panicf is equivalent to l.Printf() followed by a call to panic().
   225  func (l *Logger) Panicf(format string, v ...interface{}) {
   226  	s := fmt.Sprintf(format, v...)
   227  	l.Output(2, s)
   228  	panic(s)
   229  }
   230  
   231  // Panicln is equivalent to l.Println() followed by a call to panic().
   232  func (l *Logger) Panicln(v ...interface{}) {
   233  	s := fmt.Sprintln(v...)
   234  	l.Output(2, s)
   235  	panic(s)
   236  }
   237  
   238  // Flags returns the output flags for the logger.
   239  // The flag bits are Ldate, Ltime, and so on.
   240  func (l *Logger) Flags() int {
   241  	l.mu.Lock()
   242  	defer l.mu.Unlock()
   243  	return l.flag
   244  }
   245  
   246  // SetFlags sets the output flags for the logger.
   247  // The flag bits are Ldate, Ltime, and so on.
   248  func (l *Logger) SetFlags(flag int) {
   249  	l.mu.Lock()
   250  	defer l.mu.Unlock()
   251  	l.flag = flag
   252  }
   253  
   254  // Prefix returns the output prefix for the logger.
   255  func (l *Logger) Prefix() string {
   256  	l.mu.Lock()
   257  	defer l.mu.Unlock()
   258  	return l.prefix
   259  }
   260  
   261  // SetPrefix sets the output prefix for the logger.
   262  func (l *Logger) SetPrefix(prefix string) {
   263  	l.mu.Lock()
   264  	defer l.mu.Unlock()
   265  	l.prefix = prefix
   266  }
   267  
   268  // Writer returns the output destination for the logger.
   269  func (l *Logger) Writer() io.Writer {
   270  	l.mu.Lock()
   271  	defer l.mu.Unlock()
   272  	return l.out
   273  }
   274  
   275  // SetOutput sets the output destination for the standard logger.
   276  func SetOutput(w io.Writer) {
   277  	std.mu.Lock()
   278  	defer std.mu.Unlock()
   279  	std.out = w
   280  }
   281  
   282  // Flags returns the output flags for the standard logger.
   283  // The flag bits are Ldate, Ltime, and so on.
   284  func Flags() int {
   285  	return std.Flags()
   286  }
   287  
   288  // SetFlags sets the output flags for the standard logger.
   289  // The flag bits are Ldate, Ltime, and so on.
   290  func SetFlags(flag int) {
   291  	std.SetFlags(flag)
   292  }
   293  
   294  // Prefix returns the output prefix for the standard logger.
   295  func Prefix() string {
   296  	return std.Prefix()
   297  }
   298  
   299  // SetPrefix sets the output prefix for the standard logger.
   300  func SetPrefix(prefix string) {
   301  	std.SetPrefix(prefix)
   302  }
   303  
   304  // Writer returns the output destination for the standard logger.
   305  func Writer() io.Writer {
   306  	return std.Writer()
   307  }
   308  
   309  // These functions write to the standard logger.
   310  
   311  // Print calls Output to print to the standard logger.
   312  // Arguments are handled in the manner of fmt.Print.
   313  func Print(v ...interface{}) {
   314  	std.Output(2, fmt.Sprint(v...))
   315  }
   316  
   317  // Printf calls Output to print to the standard logger.
   318  // Arguments are handled in the manner of fmt.Printf.
   319  func Printf(format string, v ...interface{}) {
   320  	std.Output(2, fmt.Sprintf(format, v...))
   321  }
   322  
   323  // Println calls Output to print to the standard logger.
   324  // Arguments are handled in the manner of fmt.Println.
   325  func Println(v ...interface{}) {
   326  	std.Output(2, fmt.Sprintln(v...))
   327  }
   328  
   329  // Fatal is equivalent to Print() followed by a call to os.Exit(1).
   330  func Fatal(v ...interface{}) {
   331  	std.Output(2, fmt.Sprint(v...))
   332  	os.Exit(1)
   333  }
   334  
   335  // Fatalf is equivalent to Printf() followed by a call to os.Exit(1).
   336  func Fatalf(format string, v ...interface{}) {
   337  	std.Output(2, fmt.Sprintf(format, v...))
   338  	os.Exit(1)
   339  }
   340  
   341  // Fatalln is equivalent to Println() followed by a call to os.Exit(1).
   342  func Fatalln(v ...interface{}) {
   343  	std.Output(2, fmt.Sprintln(v...))
   344  	os.Exit(1)
   345  }
   346  
   347  // Panic is equivalent to Print() followed by a call to panic().
   348  func Panic(v ...interface{}) {
   349  	s := fmt.Sprint(v...)
   350  	std.Output(2, s)
   351  	panic(s)
   352  }
   353  
   354  // Panicf is equivalent to Printf() followed by a call to panic().
   355  func Panicf(format string, v ...interface{}) {
   356  	s := fmt.Sprintf(format, v...)
   357  	std.Output(2, s)
   358  	panic(s)
   359  }
   360  
   361  // Panicln is equivalent to Println() followed by a call to panic().
   362  func Panicln(v ...interface{}) {
   363  	s := fmt.Sprintln(v...)
   364  	std.Output(2, s)
   365  	panic(s)
   366  }
   367  
   368  // Output writes the output for a logging event. The string s contains
   369  // the text to print after the prefix specified by the flags of the
   370  // Logger. A newline is appended if the last character of s is not
   371  // already a newline. Calldepth is the count of the number of
   372  // frames to skip when computing the file name and line number
   373  // if Llongfile or Lshortfile is set; a value of 1 will print the details
   374  // for the caller of Output.
   375  func Output(calldepth int, s string) error {
   376  	return std.Output(calldepth+1, s) // +1 for this frame.
   377  }