...
Run Format

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

View as plain text