github.com/digdeepmining/go-atheios@v1.5.13-0.20180902133602-d5687a2e6f43/logger/glog/glog.go (about)

     1  // Go support for leveled logs, analogous to https://code.google.com/p/google-glog/
     2  //
     3  // Copyright 2013 Google Inc. All Rights Reserved.
     4  //
     5  // Licensed under the Apache License, Version 2.0 (the "License");
     6  // you may not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software
    12  // distributed under the License is distributed on an "AS IS" BASIS,
    13  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  // See the License for the specific language governing permissions and
    15  // limitations under the License.
    16  
    17  // Package glog implements logging analogous to the Google-internal C++ INFO/ERROR/V setup.
    18  // It provides functions Info, Warning, Error, Fatal, plus formatting variants such as
    19  // Infof. It also provides V-style logging controlled by the -v and -vmodule=file=2 flags.
    20  //
    21  // Basic examples:
    22  //
    23  //	glog.Info("Prepare to repel boarders")
    24  //
    25  //	glog.Fatalf("Initialization failed: %s", err)
    26  //
    27  // See the documentation for the V function for an explanation of these examples:
    28  //
    29  //	if glog.V(2) {
    30  //		glog.Info("Starting transaction...")
    31  //	}
    32  //
    33  //	glog.V(2).Infoln("Processed", nItems, "elements")
    34  //
    35  // Log output is buffered and written periodically using Flush. Programs
    36  // should call Flush before exiting to guarantee all log output is written.
    37  //
    38  // By default, all log statements write to files in a temporary directory.
    39  // This package provides several flags that modify this behavior.
    40  // As a result, flag.Parse must be called before any logging is done.
    41  //
    42  //	-logtostderr=false
    43  //		Logs are written to standard error instead of to files.
    44  //	-alsologtostderr=false
    45  //		Logs are written to standard error as well as to files.
    46  //	-stderrthreshold=ERROR
    47  //		Log events at or above this severity are logged to standard
    48  //		error as well as to files.
    49  //	-log_dir=""
    50  //		Log files will be written to this directory instead of the
    51  //		default temporary directory.
    52  //
    53  //	Other flags provide aids to debugging.
    54  //
    55  //	-log_backtrace_at=""
    56  //		When set to a file and line number holding a logging statement,
    57  //		such as
    58  //			-log_backtrace_at=gopherflakes.go:234
    59  //		a stack trace will be written to the Info log whenever execution
    60  //		hits that statement. (Unlike with -vmodule, the ".go" must be
    61  //		present.)
    62  //	-v=0
    63  //		Enable V-leveled logging at the specified level.
    64  //	-vmodule=""
    65  //		The syntax of the argument is a comma-separated list of pattern=N,
    66  //		where pattern is a literal file name or "glob" pattern matching
    67  //		and N is a V level. For instance,
    68  //
    69  //			-vmodule=gopher.go=3
    70  //		sets the V level to 3 in all Go files named "gopher.go".
    71  //
    72  //			-vmodule=foo=3
    73  //		sets V to 3 in all files of any packages whose import path ends in "foo".
    74  //
    75  //			-vmodule=foo/*=3
    76  //		sets V to 3 in all files of any packages whose import path contains "foo".
    77  package glog
    78  
    79  import (
    80  	"bufio"
    81  	"bytes"
    82  	"errors"
    83  	"fmt"
    84  	"io"
    85  	stdLog "log"
    86  	"os"
    87  	"regexp"
    88  	"runtime"
    89  	"strconv"
    90  	"strings"
    91  	"sync"
    92  	"sync/atomic"
    93  	"time"
    94  )
    95  
    96  // severity identifies the sort of log: info, warning etc. It also implements
    97  // the flag.Value interface. The -stderrthreshold flag is of type severity and
    98  // should be modified only through the flag.Value interface. The values match
    99  // the corresponding constants in C++.
   100  type severity int32 // sync/atomic int32
   101  
   102  // These constants identify the log levels in order of increasing severity.
   103  // A message written to a high-severity log file is also written to each
   104  // lower-severity log file.
   105  const (
   106  	infoLog severity = iota
   107  	warningLog
   108  	errorLog
   109  	fatalLog
   110  	numSeverity = 4
   111  )
   112  
   113  const severityChar = "IWEF"
   114  
   115  var severityName = []string{
   116  	infoLog:    "INFO",
   117  	warningLog: "WARNING",
   118  	errorLog:   "ERROR",
   119  	fatalLog:   "FATAL",
   120  }
   121  
   122  // these path prefixes are trimmed for display, but not when
   123  // matching vmodule filters.
   124  var trimPrefixes = []string{
   125  	"/github.com/atheioschain/go-atheios",
   126  	"/github.com/ethereum/ethash",
   127  }
   128  
   129  func trimToImportPath(file string) string {
   130  	if root := strings.LastIndex(file, "src/"); root != 0 {
   131  		file = file[root+3:]
   132  	}
   133  	return file
   134  }
   135  
   136  // SetV sets the global verbosity level
   137  func SetV(v int) {
   138  	logging.verbosity.set(Level(v))
   139  }
   140  
   141  // SetToStderr sets the global output style
   142  func SetToStderr(toStderr bool) {
   143  	logging.mu.Lock()
   144  	logging.toStderr = toStderr
   145  	logging.mu.Unlock()
   146  }
   147  
   148  // GetTraceLocation returns the global TraceLocation flag.
   149  func GetTraceLocation() *TraceLocation {
   150  	return &logging.traceLocation
   151  }
   152  
   153  // GetVModule returns the global verbosity pattern flag.
   154  func GetVModule() *moduleSpec {
   155  	return &logging.vmodule
   156  }
   157  
   158  // GetVerbosity returns the global verbosity level flag.
   159  func GetVerbosity() *Level {
   160  	return &logging.verbosity
   161  }
   162  
   163  // get returns the value of the severity.
   164  func (s *severity) get() severity {
   165  	return severity(atomic.LoadInt32((*int32)(s)))
   166  }
   167  
   168  // set sets the value of the severity.
   169  func (s *severity) set(val severity) {
   170  	atomic.StoreInt32((*int32)(s), int32(val))
   171  }
   172  
   173  // String is part of the flag.Value interface.
   174  func (s *severity) String() string {
   175  	return strconv.FormatInt(int64(*s), 10)
   176  }
   177  
   178  // Get is part of the flag.Value interface.
   179  func (s *severity) Get() interface{} {
   180  	return *s
   181  }
   182  
   183  // Set is part of the flag.Value interface.
   184  func (s *severity) Set(value string) error {
   185  	var threshold severity
   186  	// Is it a known name?
   187  	if v, ok := severityByName(value); ok {
   188  		threshold = v
   189  	} else {
   190  		v, err := strconv.Atoi(value)
   191  		if err != nil {
   192  			return err
   193  		}
   194  		threshold = severity(v)
   195  	}
   196  	logging.stderrThreshold.set(threshold)
   197  	return nil
   198  }
   199  
   200  func severityByName(s string) (severity, bool) {
   201  	s = strings.ToUpper(s)
   202  	for i, name := range severityName {
   203  		if name == s {
   204  			return severity(i), true
   205  		}
   206  	}
   207  	return 0, false
   208  }
   209  
   210  // OutputStats tracks the number of output lines and bytes written.
   211  type OutputStats struct {
   212  	lines int64
   213  	bytes int64
   214  }
   215  
   216  // Lines returns the number of lines written.
   217  func (s *OutputStats) Lines() int64 {
   218  	return atomic.LoadInt64(&s.lines)
   219  }
   220  
   221  // Bytes returns the number of bytes written.
   222  func (s *OutputStats) Bytes() int64 {
   223  	return atomic.LoadInt64(&s.bytes)
   224  }
   225  
   226  // Stats tracks the number of lines of output and number of bytes
   227  // per severity level. Values must be read with atomic.LoadInt64.
   228  var Stats struct {
   229  	Info, Warning, Error OutputStats
   230  }
   231  
   232  var severityStats = [numSeverity]*OutputStats{
   233  	infoLog:    &Stats.Info,
   234  	warningLog: &Stats.Warning,
   235  	errorLog:   &Stats.Error,
   236  }
   237  
   238  // Level is exported because it appears in the arguments to V and is
   239  // the type of the v flag, which can be set programmatically.
   240  // It's a distinct type because we want to discriminate it from logType.
   241  // Variables of type level are only changed under logging.mu.
   242  // The -v flag is read only with atomic ops, so the state of the logging
   243  // module is consistent.
   244  
   245  // Level is treated as a sync/atomic int32.
   246  
   247  // Level specifies a level of verbosity for V logs. *Level implements
   248  // flag.Value; the -v flag is of type Level and should be modified
   249  // only through the flag.Value interface.
   250  type Level int32
   251  
   252  // get returns the value of the Level.
   253  func (l *Level) get() Level {
   254  	return Level(atomic.LoadInt32((*int32)(l)))
   255  }
   256  
   257  // set sets the value of the Level.
   258  func (l *Level) set(val Level) {
   259  	atomic.StoreInt32((*int32)(l), int32(val))
   260  }
   261  
   262  // String is part of the flag.Value interface.
   263  func (l *Level) String() string {
   264  	return strconv.FormatInt(int64(*l), 10)
   265  }
   266  
   267  // Get is part of the flag.Value interface.
   268  func (l *Level) Get() interface{} {
   269  	return *l
   270  }
   271  
   272  // Set is part of the flag.Value interface.
   273  func (l *Level) Set(value string) error {
   274  	v, err := strconv.Atoi(value)
   275  	if err != nil {
   276  		return err
   277  	}
   278  	logging.mu.Lock()
   279  	defer logging.mu.Unlock()
   280  	logging.setVState(Level(v), logging.vmodule.filter, false)
   281  	return nil
   282  }
   283  
   284  // moduleSpec represents the setting of the -vmodule flag.
   285  type moduleSpec struct {
   286  	filter []modulePat
   287  }
   288  
   289  // modulePat contains a filter for the -vmodule flag.
   290  // It holds a verbosity level and a file pattern to match.
   291  type modulePat struct {
   292  	pattern *regexp.Regexp
   293  	level   Level
   294  }
   295  
   296  func (m *moduleSpec) String() string {
   297  	// Lock because the type is not atomic. TODO: clean this up.
   298  	logging.mu.Lock()
   299  	defer logging.mu.Unlock()
   300  	var b bytes.Buffer
   301  	for i, f := range m.filter {
   302  		if i > 0 {
   303  			b.WriteRune(',')
   304  		}
   305  		fmt.Fprintf(&b, "%s=%d", f.pattern, f.level)
   306  	}
   307  	return b.String()
   308  }
   309  
   310  // Get is part of the (Go 1.2)  flag.Getter interface. It always returns nil for this flag type since the
   311  // struct is not exported.
   312  func (m *moduleSpec) Get() interface{} {
   313  	return nil
   314  }
   315  
   316  var errVmoduleSyntax = errors.New("syntax error: expect comma-separated list of filename=N")
   317  
   318  // Syntax: -vmodule=recordio=2,file=1,gfs*=3
   319  func (m *moduleSpec) Set(value string) error {
   320  	var filter []modulePat
   321  	for _, pat := range strings.Split(value, ",") {
   322  		if len(pat) == 0 {
   323  			// Empty strings such as from a trailing comma can be ignored.
   324  			continue
   325  		}
   326  		patLev := strings.Split(pat, "=")
   327  		if len(patLev) != 2 || len(patLev[0]) == 0 || len(patLev[1]) == 0 {
   328  			return errVmoduleSyntax
   329  		}
   330  		pattern := patLev[0]
   331  		v, err := strconv.Atoi(patLev[1])
   332  		if err != nil {
   333  			return errors.New("syntax error: expect comma-separated list of filename=N")
   334  		}
   335  		if v < 0 {
   336  			return errors.New("negative value for vmodule level")
   337  		}
   338  		if v == 0 {
   339  			continue // Ignore. It's harmless but no point in paying the overhead.
   340  		}
   341  		// TODO: check syntax of filter?
   342  		re, _ := compileModulePattern(pattern)
   343  		filter = append(filter, modulePat{re, Level(v)})
   344  	}
   345  	logging.mu.Lock()
   346  	defer logging.mu.Unlock()
   347  	logging.setVState(logging.verbosity, filter, true)
   348  	return nil
   349  }
   350  
   351  // compiles a vmodule pattern to a regular expression.
   352  func compileModulePattern(pat string) (*regexp.Regexp, error) {
   353  	re := ".*"
   354  	for _, comp := range strings.Split(pat, "/") {
   355  		if comp == "*" {
   356  			re += "(/.*)?"
   357  		} else if comp != "" {
   358  			// TODO: maybe return error if comp contains *
   359  			re += "/" + regexp.QuoteMeta(comp)
   360  		}
   361  	}
   362  	if !strings.HasSuffix(pat, ".go") {
   363  		re += "/[^/]+\\.go"
   364  	}
   365  	return regexp.Compile(re + "$")
   366  }
   367  
   368  // traceLocation represents the setting of the -log_backtrace_at flag.
   369  type TraceLocation struct {
   370  	file string
   371  	line int
   372  }
   373  
   374  // isSet reports whether the trace location has been specified.
   375  // logging.mu is held.
   376  func (t *TraceLocation) isSet() bool {
   377  	return t.line > 0
   378  }
   379  
   380  // match reports whether the specified file and line matches the trace location.
   381  // The argument file name is the full path, not the basename specified in the flag.
   382  // logging.mu is held.
   383  func (t *TraceLocation) match(file string, line int) bool {
   384  	if t.line != line {
   385  		return false
   386  	}
   387  	if i := strings.LastIndex(file, "/"); i >= 0 {
   388  		file = file[i+1:]
   389  	}
   390  	return t.file == file
   391  }
   392  
   393  func (t *TraceLocation) String() string {
   394  	// Lock because the type is not atomic. TODO: clean this up.
   395  	logging.mu.Lock()
   396  	defer logging.mu.Unlock()
   397  	return fmt.Sprintf("%s:%d", t.file, t.line)
   398  }
   399  
   400  // Get is part of the (Go 1.2) flag.Getter interface. It always returns nil for this flag type since the
   401  // struct is not exported
   402  func (t *TraceLocation) Get() interface{} {
   403  	return nil
   404  }
   405  
   406  var errTraceSyntax = errors.New("syntax error: expect file.go:234")
   407  
   408  // Syntax: -log_backtrace_at=gopherflakes.go:234
   409  // Note that unlike vmodule the file extension is included here.
   410  func (t *TraceLocation) Set(value string) error {
   411  	if value == "" {
   412  		// Unset.
   413  		logging.mu.Lock()
   414  		t.line = 0
   415  		t.file = ""
   416  		logging.mu.Unlock()
   417  		return nil
   418  	}
   419  
   420  	fields := strings.Split(value, ":")
   421  	if len(fields) != 2 {
   422  		return errTraceSyntax
   423  	}
   424  	file, line := fields[0], fields[1]
   425  	if !strings.Contains(file, ".") {
   426  		return errTraceSyntax
   427  	}
   428  	v, err := strconv.Atoi(line)
   429  	if err != nil {
   430  		return errTraceSyntax
   431  	}
   432  	if v <= 0 {
   433  		return errors.New("negative or zero value for level")
   434  	}
   435  	logging.mu.Lock()
   436  	defer logging.mu.Unlock()
   437  	t.line = v
   438  	t.file = file
   439  	return nil
   440  }
   441  
   442  // flushSyncWriter is the interface satisfied by logging destinations.
   443  type flushSyncWriter interface {
   444  	Flush() error
   445  	Sync() error
   446  	io.Writer
   447  }
   448  
   449  func init() {
   450  	//flag.BoolVar(&logging.toStderr, "logtostderr", false, "log to standard error instead of files")
   451  	//flag.BoolVar(&logging.alsoToStderr, "alsologtostderr", false, "log to standard error as well as files")
   452  	//flag.Var(&logging.verbosity, "v", "log level for V logs")
   453  	//flag.Var(&logging.stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr")
   454  	//flag.Var(&logging.vmodule, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging")
   455  	//flag.Var(&logging.traceLocation, "log_backtrace_at", "when logging hits line file:N, emit a stack trace")
   456  
   457  	// Default stderrThreshold is ERROR.
   458  	logging.stderrThreshold = errorLog
   459  	logging.setVState(3, nil, false)
   460  	go logging.flushDaemon()
   461  }
   462  
   463  // Flush flushes all pending log I/O.
   464  func Flush() {
   465  	logging.lockAndFlushAll()
   466  }
   467  
   468  // loggingT collects all the global state of the logging setup.
   469  type loggingT struct {
   470  	// Boolean flags. Not handled atomically because the flag.Value interface
   471  	// does not let us avoid the =true, and that shorthand is necessary for
   472  	// compatibility. TODO: does this matter enough to fix? Seems unlikely.
   473  	toStderr     bool // The -logtostderr flag.
   474  	alsoToStderr bool // The -alsologtostderr flag.
   475  
   476  	// Level flag. Handled atomically.
   477  	stderrThreshold severity // The -stderrthreshold flag.
   478  
   479  	// freeList is a list of byte buffers, maintained under freeListMu.
   480  	freeList *buffer
   481  	// freeListMu maintains the free list. It is separate from the main mutex
   482  	// so buffers can be grabbed and printed to without holding the main lock,
   483  	// for better parallelization.
   484  	freeListMu sync.Mutex
   485  
   486  	// mu protects the remaining elements of this structure and is
   487  	// used to synchronize logging.
   488  	mu sync.Mutex
   489  	// file holds writer for each of the log types.
   490  	file [numSeverity]flushSyncWriter
   491  	// pcs is used in V to avoid an allocation when computing the caller's PC.
   492  	pcs [1]uintptr
   493  	// vmap is a cache of the V Level for each V() call site, identified by PC.
   494  	// It is wiped whenever the vmodule flag changes state.
   495  	vmap map[uintptr]Level
   496  	// filterLength stores the length of the vmodule filter chain. If greater
   497  	// than zero, it means vmodule is enabled. It may be read safely
   498  	// using sync.LoadInt32, but is only modified under mu.
   499  	filterLength int32
   500  	// traceLocation is the state of the -log_backtrace_at flag.
   501  	traceLocation TraceLocation
   502  	// These flags are modified only under lock, although verbosity may be fetched
   503  	// safely using atomic.LoadInt32.
   504  	vmodule   moduleSpec // The state of the -vmodule flag.
   505  	verbosity Level      // V logging level, the value of the -v flag/
   506  }
   507  
   508  // buffer holds a byte Buffer for reuse. The zero value is ready for use.
   509  type buffer struct {
   510  	bytes.Buffer
   511  	tmp  [64]byte // temporary byte array for creating headers.
   512  	next *buffer
   513  }
   514  
   515  var logging loggingT
   516  
   517  // setVState sets a consistent state for V logging.
   518  // l.mu is held.
   519  func (l *loggingT) setVState(verbosity Level, filter []modulePat, setFilter bool) {
   520  	// Turn verbosity off so V will not fire while we are in transition.
   521  	logging.verbosity.set(0)
   522  	// Ditto for filter length.
   523  	atomic.StoreInt32(&logging.filterLength, 0)
   524  
   525  	// Set the new filters and wipe the pc->Level map if the filter has changed.
   526  	if setFilter {
   527  		logging.vmodule.filter = filter
   528  		logging.vmap = make(map[uintptr]Level)
   529  	}
   530  
   531  	// Things are consistent now, so enable filtering and verbosity.
   532  	// They are enabled in order opposite to that in V.
   533  	atomic.StoreInt32(&logging.filterLength, int32(len(filter)))
   534  	logging.verbosity.set(verbosity)
   535  }
   536  
   537  // getBuffer returns a new, ready-to-use buffer.
   538  func (l *loggingT) getBuffer() *buffer {
   539  	l.freeListMu.Lock()
   540  	b := l.freeList
   541  	if b != nil {
   542  		l.freeList = b.next
   543  	}
   544  	l.freeListMu.Unlock()
   545  	if b == nil {
   546  		b = new(buffer)
   547  	} else {
   548  		b.next = nil
   549  		b.Reset()
   550  	}
   551  	return b
   552  }
   553  
   554  // putBuffer returns a buffer to the free list.
   555  func (l *loggingT) putBuffer(b *buffer) {
   556  	if b.Len() >= 256 {
   557  		// Let big buffers die a natural death.
   558  		return
   559  	}
   560  	l.freeListMu.Lock()
   561  	b.next = l.freeList
   562  	l.freeList = b
   563  	l.freeListMu.Unlock()
   564  }
   565  
   566  var timeNow = time.Now // Stubbed out for testing.
   567  
   568  /*
   569  header formats a log header as defined by the C++ implementation.
   570  It returns a buffer containing the formatted header and the user's file and line number.
   571  The depth specifies how many stack frames above lives the source line to be identified in the log message.
   572  
   573  Log lines have this form:
   574  	Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg...
   575  where the fields are defined as follows:
   576  	L                A single character, representing the log level (eg 'I' for INFO)
   577  	mm               The month (zero padded; ie May is '05')
   578  	dd               The day (zero padded)
   579  	hh:mm:ss.uuuuuu  Time in hours, minutes and fractional seconds
   580  	threadid         The space-padded thread ID as returned by GetTID()
   581  	file             The file name
   582  	line             The line number
   583  	msg              The user-supplied message
   584  */
   585  func (l *loggingT) header(s severity, depth int) (*buffer, string, int) {
   586  	_, file, line, ok := runtime.Caller(3 + depth)
   587  	if !ok {
   588  		file = "???"
   589  		line = 1
   590  	} else {
   591  		file = trimToImportPath(file)
   592  		for _, p := range trimPrefixes {
   593  			if strings.HasPrefix(file, p) {
   594  				file = file[len(p):]
   595  				break
   596  			}
   597  		}
   598  		file = file[1:] // drop '/'
   599  	}
   600  	return l.formatHeader(s, file, line), file, line
   601  }
   602  
   603  // formatHeader formats a log header using the provided file name and line number.
   604  func (l *loggingT) formatHeader(s severity, file string, line int) *buffer {
   605  	now := timeNow()
   606  	if line < 0 {
   607  		line = 0 // not a real line number, but acceptable to someDigits
   608  	}
   609  	if s > fatalLog {
   610  		s = infoLog // for safety.
   611  	}
   612  	buf := l.getBuffer()
   613  
   614  	// Avoid Fprintf, for speed. The format is so simple that we can do it quickly by hand.
   615  	// It's worth about 3X. Fprintf is hard.
   616  	_, month, day := now.Date()
   617  	hour, minute, second := now.Clock()
   618  	// Lmmdd hh:mm:ss.uuuuuu threadid file:line]
   619  	buf.tmp[0] = severityChar[s]
   620  	buf.twoDigits(1, int(month))
   621  	buf.twoDigits(3, day)
   622  	buf.tmp[5] = ' '
   623  	buf.twoDigits(6, hour)
   624  	buf.tmp[8] = ':'
   625  	buf.twoDigits(9, minute)
   626  	buf.tmp[11] = ':'
   627  	buf.twoDigits(12, second)
   628  	buf.tmp[14] = '.'
   629  	buf.nDigits(6, 15, now.Nanosecond()/1000, '0')
   630  	buf.tmp[21] = ' '
   631  	buf.Write(buf.tmp[:22])
   632  	buf.WriteString(file)
   633  	buf.tmp[0] = ':'
   634  	n := buf.someDigits(1, line)
   635  	buf.tmp[n+1] = ']'
   636  	buf.tmp[n+2] = ' '
   637  	buf.Write(buf.tmp[:n+3])
   638  	return buf
   639  }
   640  
   641  // Some custom tiny helper functions to print the log header efficiently.
   642  
   643  const digits = "0123456789"
   644  
   645  // twoDigits formats a zero-prefixed two-digit integer at buf.tmp[i].
   646  func (buf *buffer) twoDigits(i, d int) {
   647  	buf.tmp[i+1] = digits[d%10]
   648  	d /= 10
   649  	buf.tmp[i] = digits[d%10]
   650  }
   651  
   652  // nDigits formats an n-digit integer at buf.tmp[i],
   653  // padding with pad on the left.
   654  // It assumes d >= 0.
   655  func (buf *buffer) nDigits(n, i, d int, pad byte) {
   656  	j := n - 1
   657  	for ; j >= 0 && d > 0; j-- {
   658  		buf.tmp[i+j] = digits[d%10]
   659  		d /= 10
   660  	}
   661  	for ; j >= 0; j-- {
   662  		buf.tmp[i+j] = pad
   663  	}
   664  }
   665  
   666  // someDigits formats a zero-prefixed variable-width integer at buf.tmp[i].
   667  func (buf *buffer) someDigits(i, d int) int {
   668  	// Print into the top, then copy down. We know there's space for at least
   669  	// a 10-digit number.
   670  	j := len(buf.tmp)
   671  	for {
   672  		j--
   673  		buf.tmp[j] = digits[d%10]
   674  		d /= 10
   675  		if d == 0 {
   676  			break
   677  		}
   678  	}
   679  	return copy(buf.tmp[i:], buf.tmp[j:])
   680  }
   681  
   682  func (l *loggingT) println(s severity, args ...interface{}) {
   683  	buf, file, line := l.header(s, 0)
   684  	fmt.Fprintln(buf, args...)
   685  	l.output(s, buf, file, line, false)
   686  }
   687  
   688  func (l *loggingT) print(s severity, args ...interface{}) {
   689  	l.printDepth(s, 1, args...)
   690  }
   691  
   692  func (l *loggingT) printDepth(s severity, depth int, args ...interface{}) {
   693  	buf, file, line := l.header(s, depth)
   694  	fmt.Fprint(buf, args...)
   695  	if buf.Bytes()[buf.Len()-1] != '\n' {
   696  		buf.WriteByte('\n')
   697  	}
   698  	l.output(s, buf, file, line, false)
   699  }
   700  
   701  func (l *loggingT) printfmt(s severity, format string, args ...interface{}) {
   702  	buf, file, line := l.header(s, 0)
   703  	fmt.Fprintf(buf, format, args...)
   704  	if buf.Bytes()[buf.Len()-1] != '\n' {
   705  		buf.WriteByte('\n')
   706  	}
   707  	l.output(s, buf, file, line, false)
   708  }
   709  
   710  // printWithFileLine behaves like print but uses the provided file and line number.  If
   711  // alsoLogToStderr is true, the log message always appears on standard error; it
   712  // will also appear in the log file unless --logtostderr is set.
   713  func (l *loggingT) printWithFileLine(s severity, file string, line int, alsoToStderr bool, args ...interface{}) {
   714  	buf := l.formatHeader(s, file, line)
   715  	fmt.Fprint(buf, args...)
   716  	if buf.Bytes()[buf.Len()-1] != '\n' {
   717  		buf.WriteByte('\n')
   718  	}
   719  	l.output(s, buf, file, line, alsoToStderr)
   720  }
   721  
   722  // output writes the data to the log files and releases the buffer.
   723  func (l *loggingT) output(s severity, buf *buffer, file string, line int, alsoToStderr bool) {
   724  	l.mu.Lock()
   725  	if l.traceLocation.isSet() {
   726  		if l.traceLocation.match(file, line) {
   727  			buf.Write(stacks(false))
   728  		}
   729  	}
   730  	data := buf.Bytes()
   731  	if l.toStderr {
   732  		os.Stderr.Write(data)
   733  	} else {
   734  		if alsoToStderr || l.alsoToStderr || s >= l.stderrThreshold.get() {
   735  			os.Stderr.Write(data)
   736  		}
   737  		if l.file[s] == nil {
   738  			if err := l.createFiles(s); err != nil {
   739  				os.Stderr.Write(data) // Make sure the message appears somewhere.
   740  				l.exit(err)
   741  			}
   742  		}
   743  		switch s {
   744  		case fatalLog:
   745  			l.file[fatalLog].Write(data)
   746  			fallthrough
   747  		case errorLog:
   748  			l.file[errorLog].Write(data)
   749  			fallthrough
   750  		case warningLog:
   751  			l.file[warningLog].Write(data)
   752  			fallthrough
   753  		case infoLog:
   754  			l.file[infoLog].Write(data)
   755  		}
   756  	}
   757  	if s == fatalLog {
   758  		// If we got here via Exit rather than Fatal, print no stacks.
   759  		if atomic.LoadUint32(&fatalNoStacks) > 0 {
   760  			l.mu.Unlock()
   761  			timeoutFlush(10 * time.Second)
   762  			os.Exit(1)
   763  		}
   764  		// Dump all goroutine stacks before exiting.
   765  		// First, make sure we see the trace for the current goroutine on standard error.
   766  		// If -logtostderr has been specified, the loop below will do that anyway
   767  		// as the first stack in the full dump.
   768  		if !l.toStderr {
   769  			os.Stderr.Write(stacks(false))
   770  		}
   771  		// Write the stack trace for all goroutines to the files.
   772  		trace := stacks(true)
   773  		logExitFunc = func(error) {} // If we get a write error, we'll still exit below.
   774  		for log := fatalLog; log >= infoLog; log-- {
   775  			if f := l.file[log]; f != nil { // Can be nil if -logtostderr is set.
   776  				f.Write(trace)
   777  			}
   778  		}
   779  		l.mu.Unlock()
   780  		timeoutFlush(10 * time.Second)
   781  		os.Exit(255) // C++ uses -1, which is silly because it's anded with 255 anyway.
   782  	}
   783  	l.putBuffer(buf)
   784  	l.mu.Unlock()
   785  	if stats := severityStats[s]; stats != nil {
   786  		atomic.AddInt64(&stats.lines, 1)
   787  		atomic.AddInt64(&stats.bytes, int64(len(data)))
   788  	}
   789  }
   790  
   791  // timeoutFlush calls Flush and returns when it completes or after timeout
   792  // elapses, whichever happens first.  This is needed because the hooks invoked
   793  // by Flush may deadlock when glog.Fatal is called from a hook that holds
   794  // a lock.
   795  func timeoutFlush(timeout time.Duration) {
   796  	done := make(chan bool, 1)
   797  	go func() {
   798  		Flush() // calls logging.lockAndFlushAll()
   799  		done <- true
   800  	}()
   801  	select {
   802  	case <-done:
   803  	case <-time.After(timeout):
   804  		fmt.Fprintln(os.Stderr, "glog: Flush took longer than", timeout)
   805  	}
   806  }
   807  
   808  // stacks is a wrapper for runtime.Stack that attempts to recover the data for all goroutines.
   809  func stacks(all bool) []byte {
   810  	// We don't know how big the traces are, so grow a few times if they don't fit. Start large, though.
   811  	n := 10000
   812  	if all {
   813  		n = 100000
   814  	}
   815  	var trace []byte
   816  	for i := 0; i < 5; i++ {
   817  		trace = make([]byte, n)
   818  		nbytes := runtime.Stack(trace, all)
   819  		if nbytes < len(trace) {
   820  			return trace[:nbytes]
   821  		}
   822  		n *= 2
   823  	}
   824  	return trace
   825  }
   826  
   827  // logExitFunc provides a simple mechanism to override the default behavior
   828  // of exiting on error. Used in testing and to guarantee we reach a required exit
   829  // for fatal logs. Instead, exit could be a function rather than a method but that
   830  // would make its use clumsier.
   831  var logExitFunc func(error)
   832  
   833  // exit is called if there is trouble creating or writing log files.
   834  // It flushes the logs and exits the program; there's no point in hanging around.
   835  // l.mu is held.
   836  func (l *loggingT) exit(err error) {
   837  	fmt.Fprintf(os.Stderr, "log: exiting because of error: %s\n", err)
   838  	// If logExitFunc is set, we do that instead of exiting.
   839  	if logExitFunc != nil {
   840  		logExitFunc(err)
   841  		return
   842  	}
   843  	l.flushAll()
   844  	os.Exit(2)
   845  }
   846  
   847  // syncBuffer joins a bufio.Writer to its underlying file, providing access to the
   848  // file's Sync method and providing a wrapper for the Write method that provides log
   849  // file rotation. There are conflicting methods, so the file cannot be embedded.
   850  // l.mu is held for all its methods.
   851  type syncBuffer struct {
   852  	logger *loggingT
   853  	*bufio.Writer
   854  	file   *os.File
   855  	sev    severity
   856  	nbytes uint64 // The number of bytes written to this file
   857  }
   858  
   859  func (sb *syncBuffer) Sync() error {
   860  	return sb.file.Sync()
   861  }
   862  
   863  func (sb *syncBuffer) Write(p []byte) (n int, err error) {
   864  	if sb.nbytes+uint64(len(p)) >= MaxSize {
   865  		if err := sb.rotateFile(time.Now()); err != nil {
   866  			sb.logger.exit(err)
   867  		}
   868  	}
   869  	n, err = sb.Writer.Write(p)
   870  	sb.nbytes += uint64(n)
   871  	if err != nil {
   872  		sb.logger.exit(err)
   873  	}
   874  	return
   875  }
   876  
   877  // rotateFile closes the syncBuffer's file and starts a new one.
   878  func (sb *syncBuffer) rotateFile(now time.Time) error {
   879  	if sb.file != nil {
   880  		sb.Flush()
   881  		sb.file.Close()
   882  	}
   883  	var err error
   884  	sb.file, _, err = create(severityName[sb.sev], now)
   885  	sb.nbytes = 0
   886  	if err != nil {
   887  		return err
   888  	}
   889  
   890  	sb.Writer = bufio.NewWriterSize(sb.file, bufferSize)
   891  
   892  	// Write header.
   893  	var buf bytes.Buffer
   894  	fmt.Fprintf(&buf, "Log file created at: %s\n", now.Format("2006/01/02 15:04:05"))
   895  	fmt.Fprintf(&buf, "Running on machine: %s\n", host)
   896  	fmt.Fprintf(&buf, "Binary: Built with %s %s for %s/%s\n", runtime.Compiler, runtime.Version(), runtime.GOOS, runtime.GOARCH)
   897  	fmt.Fprintf(&buf, "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg\n")
   898  	n, err := sb.file.Write(buf.Bytes())
   899  	sb.nbytes += uint64(n)
   900  	return err
   901  }
   902  
   903  // bufferSize sizes the buffer associated with each log file. It's large
   904  // so that log records can accumulate without the logging thread blocking
   905  // on disk I/O. The flushDaemon will block instead.
   906  const bufferSize = 256 * 1024
   907  
   908  // createFiles creates all the log files for severity from sev down to infoLog.
   909  // l.mu is held.
   910  func (l *loggingT) createFiles(sev severity) error {
   911  	now := time.Now()
   912  	// Files are created in decreasing severity order, so as soon as we find one
   913  	// has already been created, we can stop.
   914  	for s := sev; s >= infoLog && l.file[s] == nil; s-- {
   915  		sb := &syncBuffer{
   916  			logger: l,
   917  			sev:    s,
   918  		}
   919  		if err := sb.rotateFile(now); err != nil {
   920  			return err
   921  		}
   922  		l.file[s] = sb
   923  	}
   924  	return nil
   925  }
   926  
   927  const flushInterval = 30 * time.Second
   928  
   929  // flushDaemon periodically flushes the log file buffers.
   930  func (l *loggingT) flushDaemon() {
   931  	for range time.NewTicker(flushInterval).C {
   932  		l.lockAndFlushAll()
   933  	}
   934  }
   935  
   936  // lockAndFlushAll is like flushAll but locks l.mu first.
   937  func (l *loggingT) lockAndFlushAll() {
   938  	l.mu.Lock()
   939  	l.flushAll()
   940  	l.mu.Unlock()
   941  }
   942  
   943  // flushAll flushes all the logs and attempts to "sync" their data to disk.
   944  // l.mu is held.
   945  func (l *loggingT) flushAll() {
   946  	// Flush from fatal down, in case there's trouble flushing.
   947  	for s := fatalLog; s >= infoLog; s-- {
   948  		file := l.file[s]
   949  		if file != nil {
   950  			file.Flush() // ignore error
   951  			file.Sync()  // ignore error
   952  		}
   953  	}
   954  }
   955  
   956  // CopyStandardLogTo arranges for messages written to the Go "log" package's
   957  // default logs to also appear in the Google logs for the named and lower
   958  // severities.  Subsequent changes to the standard log's default output location
   959  // or format may break this behavior.
   960  //
   961  // Valid names are "INFO", "WARNING", "ERROR", and "FATAL".  If the name is not
   962  // recognized, CopyStandardLogTo panics.
   963  func CopyStandardLogTo(name string) {
   964  	sev, ok := severityByName(name)
   965  	if !ok {
   966  		panic(fmt.Sprintf("log.CopyStandardLogTo(%q): unrecognized severity name", name))
   967  	}
   968  	// Set a log format that captures the user's file and line:
   969  	//   d.go:23: message
   970  	stdLog.SetFlags(stdLog.Lshortfile)
   971  	stdLog.SetOutput(logBridge(sev))
   972  }
   973  
   974  // logBridge provides the Write method that enables CopyStandardLogTo to connect
   975  // Go's standard logs to the logs provided by this package.
   976  type logBridge severity
   977  
   978  // Write parses the standard logging line and passes its components to the
   979  // logger for severity(lb).
   980  func (lb logBridge) Write(b []byte) (n int, err error) {
   981  	var (
   982  		file = "???"
   983  		line = 1
   984  		text string
   985  	)
   986  	// Split "d.go:23: message" into "d.go", "23", and "message".
   987  	if parts := bytes.SplitN(b, []byte{':'}, 3); len(parts) != 3 || len(parts[0]) < 1 || len(parts[2]) < 1 {
   988  		text = fmt.Sprintf("bad log format: %s", b)
   989  	} else {
   990  		file = string(parts[0])
   991  		text = string(parts[2][1:]) // skip leading space
   992  		line, err = strconv.Atoi(string(parts[1]))
   993  		if err != nil {
   994  			text = fmt.Sprintf("bad line number: %s", b)
   995  			line = 1
   996  		}
   997  	}
   998  	// printWithFileLine with alsoToStderr=true, so standard log messages
   999  	// always appear on standard error.
  1000  	logging.printWithFileLine(severity(lb), file, line, true, text)
  1001  	return len(b), nil
  1002  }
  1003  
  1004  // setV computes and remembers the V level for a given PC
  1005  // when vmodule is enabled.
  1006  // File pattern matching takes the basename of the file, stripped
  1007  // of its .go suffix, and uses filepath.Match, which is a little more
  1008  // general than the *? matching used in C++.
  1009  // l.mu is held.
  1010  func (l *loggingT) setV(pc uintptr) Level {
  1011  	fn := runtime.FuncForPC(pc)
  1012  	file, _ := fn.FileLine(pc)
  1013  	file = trimToImportPath(file)
  1014  	for _, filter := range l.vmodule.filter {
  1015  		if filter.pattern.MatchString(file) {
  1016  			l.vmap[pc] = filter.level
  1017  			return filter.level
  1018  		}
  1019  	}
  1020  	l.vmap[pc] = 0
  1021  	return 0
  1022  }
  1023  
  1024  // Verbose is a boolean type that implements Infof (like Printf) etc.
  1025  // See the documentation of V for more information.
  1026  type Verbose bool
  1027  
  1028  // V reports whether verbosity at the call site is at least the requested level.
  1029  // The returned value is a boolean of type Verbose, which implements Info, Infoln
  1030  // and Infof. These methods will write to the Info log if called.
  1031  // Thus, one may write either
  1032  //	if glog.V(2) { glog.Info("log this") }
  1033  // or
  1034  //	glog.V(2).Info("log this")
  1035  // The second form is shorter but the first is cheaper if logging is off because it does
  1036  // not evaluate its arguments.
  1037  //
  1038  // Whether an individual call to V generates a log record depends on the setting of
  1039  // the -v and --vmodule flags; both are off by default. If the level in the call to
  1040  // V is at least the value of -v, or of -vmodule for the source file containing the
  1041  // call, the V call will log.
  1042  func V(level Level) Verbose {
  1043  	// This function tries hard to be cheap unless there's work to do.
  1044  	// The fast path is two atomic loads and compares.
  1045  
  1046  	// Here is a cheap but safe test to see if V logging is enabled globally.
  1047  	if logging.verbosity.get() >= level {
  1048  		return Verbose(true)
  1049  	}
  1050  
  1051  	// It's off globally but it vmodule may still be set.
  1052  	// Here is another cheap but safe test to see if vmodule is enabled.
  1053  	if atomic.LoadInt32(&logging.filterLength) > 0 {
  1054  		// Now we need a proper lock to use the logging structure. The pcs field
  1055  		// is shared so we must lock before accessing it. This is fairly expensive,
  1056  		// but if V logging is enabled we're slow anyway.
  1057  		logging.mu.Lock()
  1058  		defer logging.mu.Unlock()
  1059  		if runtime.Callers(2, logging.pcs[:]) == 0 {
  1060  			return Verbose(false)
  1061  		}
  1062  		v, ok := logging.vmap[logging.pcs[0]]
  1063  		if !ok {
  1064  			v = logging.setV(logging.pcs[0])
  1065  		}
  1066  		return Verbose(v >= level)
  1067  	}
  1068  	return Verbose(false)
  1069  }
  1070  
  1071  // Info is equivalent to the global Info function, guarded by the value of v.
  1072  // See the documentation of V for usage.
  1073  func (v Verbose) Info(args ...interface{}) {
  1074  	if v {
  1075  		logging.print(infoLog, args...)
  1076  	}
  1077  }
  1078  
  1079  // Infoln is equivalent to the global Infoln function, guarded by the value of v.
  1080  // See the documentation of V for usage.
  1081  func (v Verbose) Infoln(args ...interface{}) {
  1082  	if v {
  1083  		logging.println(infoLog, args...)
  1084  	}
  1085  }
  1086  
  1087  // Infof is equivalent to the global Infof function, guarded by the value of v.
  1088  // See the documentation of V for usage.
  1089  func (v Verbose) Infof(format string, args ...interface{}) {
  1090  	if v {
  1091  		logging.printfmt(infoLog, format, args...)
  1092  	}
  1093  }
  1094  
  1095  // Info logs to the INFO log.
  1096  // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
  1097  func Info(args ...interface{}) {
  1098  	logging.print(infoLog, args...)
  1099  }
  1100  
  1101  // InfoDepth acts as Info but uses depth to determine which call frame to log.
  1102  // InfoDepth(0, "msg") is the same as Info("msg").
  1103  func InfoDepth(depth int, args ...interface{}) {
  1104  	logging.printDepth(infoLog, depth, args...)
  1105  }
  1106  
  1107  // Infoln logs to the INFO log.
  1108  // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
  1109  func Infoln(args ...interface{}) {
  1110  	logging.print(infoLog, args...)
  1111  }
  1112  
  1113  // Infof logs to the INFO log.
  1114  // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
  1115  func Infof(format string, args ...interface{}) {
  1116  	logging.printfmt(infoLog, format, args...)
  1117  }
  1118  
  1119  // Warning logs to the WARNING and INFO logs.
  1120  // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
  1121  func Warning(args ...interface{}) {
  1122  	logging.print(warningLog, args...)
  1123  }
  1124  
  1125  // WarningDepth acts as Warning but uses depth to determine which call frame to log.
  1126  // WarningDepth(0, "msg") is the same as Warning("msg").
  1127  func WarningDepth(depth int, args ...interface{}) {
  1128  	logging.printDepth(warningLog, depth, args...)
  1129  }
  1130  
  1131  // Warningln logs to the WARNING and INFO logs.
  1132  // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
  1133  func Warningln(args ...interface{}) {
  1134  	logging.println(warningLog, args...)
  1135  }
  1136  
  1137  // Warningf logs to the WARNING and INFO logs.
  1138  // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
  1139  func Warningf(format string, args ...interface{}) {
  1140  	logging.printfmt(warningLog, format, args...)
  1141  }
  1142  
  1143  // Error logs to the ERROR, WARNING, and INFO logs.
  1144  // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
  1145  func Error(args ...interface{}) {
  1146  	logging.print(errorLog, args...)
  1147  }
  1148  
  1149  // ErrorDepth acts as Error but uses depth to determine which call frame to log.
  1150  // ErrorDepth(0, "msg") is the same as Error("msg").
  1151  func ErrorDepth(depth int, args ...interface{}) {
  1152  	logging.printDepth(errorLog, depth, args...)
  1153  }
  1154  
  1155  // Errorln logs to the ERROR, WARNING, and INFO logs.
  1156  // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
  1157  func Errorln(args ...interface{}) {
  1158  	logging.println(errorLog, args...)
  1159  }
  1160  
  1161  // Errorf logs to the ERROR, WARNING, and INFO logs.
  1162  // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
  1163  func Errorf(format string, args ...interface{}) {
  1164  	logging.printfmt(errorLog, format, args...)
  1165  }
  1166  
  1167  // Fatal logs to the FATAL, ERROR, WARNING, and INFO logs,
  1168  // including a stack trace of all running goroutines, then calls os.Exit(255).
  1169  // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
  1170  func Fatal(args ...interface{}) {
  1171  	logging.print(fatalLog, args...)
  1172  }
  1173  
  1174  // FatalDepth acts as Fatal but uses depth to determine which call frame to log.
  1175  // FatalDepth(0, "msg") is the same as Fatal("msg").
  1176  func FatalDepth(depth int, args ...interface{}) {
  1177  	logging.printDepth(fatalLog, depth, args...)
  1178  }
  1179  
  1180  // Fatalln logs to the FATAL, ERROR, WARNING, and INFO logs,
  1181  // including a stack trace of all running goroutines, then calls os.Exit(255).
  1182  // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
  1183  func Fatalln(args ...interface{}) {
  1184  	logging.println(fatalLog, args...)
  1185  }
  1186  
  1187  // Fatalf logs to the FATAL, ERROR, WARNING, and INFO logs,
  1188  // including a stack trace of all running goroutines, then calls os.Exit(255).
  1189  // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
  1190  func Fatalf(format string, args ...interface{}) {
  1191  	logging.printfmt(fatalLog, format, args...)
  1192  }
  1193  
  1194  // fatalNoStacks is non-zero if we are to exit without dumping goroutine stacks.
  1195  // It allows Exit and relatives to use the Fatal logs.
  1196  var fatalNoStacks uint32
  1197  
  1198  // Exit logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
  1199  // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
  1200  func Exit(args ...interface{}) {
  1201  	atomic.StoreUint32(&fatalNoStacks, 1)
  1202  	logging.print(fatalLog, args...)
  1203  }
  1204  
  1205  // ExitDepth acts as Exit but uses depth to determine which call frame to log.
  1206  // ExitDepth(0, "msg") is the same as Exit("msg").
  1207  func ExitDepth(depth int, args ...interface{}) {
  1208  	atomic.StoreUint32(&fatalNoStacks, 1)
  1209  	logging.printDepth(fatalLog, depth, args...)
  1210  }
  1211  
  1212  // Exitln logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
  1213  func Exitln(args ...interface{}) {
  1214  	atomic.StoreUint32(&fatalNoStacks, 1)
  1215  	logging.println(fatalLog, args...)
  1216  }
  1217  
  1218  // Exitf logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
  1219  // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
  1220  func Exitf(format string, args ...interface{}) {
  1221  	atomic.StoreUint32(&fatalNoStacks, 1)
  1222  	logging.printfmt(fatalLog, format, args...)
  1223  }