github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/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  // Modifications copyright 2017 ETC Dev Team. All Rights Reserved.
     5  //
     6  // Licensed under the Apache License, Version 2.0 (the "License");
     7  // you may not use this file except in compliance with the License.
     8  // You may obtain a copy of the License at
     9  //
    10  //     http://www.apache.org/licenses/LICENSE-2.0
    11  //
    12  // Unless required by applicable law or agreed to in writing, software
    13  // distributed under the License is distributed on an "AS IS" BASIS,
    14  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15  // See the License for the specific language governing permissions and
    16  // limitations under the License.
    17  
    18  // Package glog implements logging analogous to the Google-internal C++ INFO/ERROR/V setup.
    19  // It provides functions Info, Warning, Error, Fatal, plus formatting variants such as
    20  // Infof. It also provides V-style logging controlled by the -v and -vmodule=file=2 flags.
    21  //
    22  // Basic examples:
    23  //
    24  //	glog.Info("Prepare to repel boarders")
    25  //
    26  //	glog.Fatalf("Initialization failed: %s", err)
    27  //
    28  // See the documentation for the V function for an explanation of these examples:
    29  //
    30  //	if glog.V(2) {
    31  //		glog.Info("Starting transaction...")
    32  //	}
    33  //
    34  //	glog.V(2).Infoln("Processed", nItems, "elements")
    35  //
    36  // Log output is buffered and written periodically using Flush. Programs
    37  // should call Flush before exiting to guarantee all log output is written.
    38  //
    39  // By default, all log statements write to files in a temporary directory.
    40  // This package provides several flags that modify this behavior.
    41  // As a result, flag.Parse must be called before any logging is done.
    42  //
    43  //	-logtostderr=false
    44  //		Logs are written to standard error instead of to files.
    45  //	-alsologtostderr=false
    46  //		Logs are written to standard error as well as to files.
    47  //	-stderrthreshold=ERROR
    48  //		Log events at or above this severity are logged to standard
    49  //		error as well as to files.
    50  //	-log_dir=""
    51  //		Log files will be written to this directory instead of the
    52  //		default temporary directory.
    53  //
    54  //	Other flags provide aids to debugging.
    55  //
    56  //	-log_backtrace_at=""
    57  //		When set to a file and line number holding a logging statement,
    58  //		such as
    59  //			-log_backtrace_at=gopherflakes.go:234
    60  //		a stack trace will be written to the Info log whenever execution
    61  //		hits that statement. (Unlike with -vmodule, the ".go" must be
    62  //		present.)
    63  //	-v=0
    64  //		Enable V-leveled logging at the specified level.
    65  //	-vmodule=""
    66  //		The syntax of the argument is a comma-separated list of pattern=N,
    67  //		where pattern is a literal file name or "glob" pattern matching
    68  //		and N is a V level. For instance,
    69  //
    70  //	-vmodule=gopher.go=3
    71  //		sets the V level to 3 in all Go files named "gopher.go".
    72  //
    73  //	-vmodule=foo=3
    74  //		sets V to 3 in all files of any packages whose import path ends in "foo".
    75  //
    76  //	-vmodule=foo/*=3
    77  //		sets V to 3 in all files of any packages whose import path contains "foo".
    78  //
    79  // This fork of original golang/glog adds log rotation functionality.
    80  // Logs are rotated after reaching file size limit or age limit. Additionally
    81  // limiting total amount of logs is supported (also by both size and age).
    82  // To keep it simple, log-rotation is configured with package-level variables:
    83  //  - MaxSize - maximum file size (in bytes) - default value: 1024 * 1024 * 1800
    84  //  - MinSize - minimum file size (in bytes) - default 0 (even empty file can be rotated)
    85  //  - MaxTotalSize - maximum size of all files (in bytes) - default 0 (do not remove old files)
    86  //  - RotationInterval - how often log should be rotated - default Never
    87  //  - MaxAge - maximum age (time.Duration) of log file - default 0 (do not remove old files)
    88  //  - Compress - whether to GZIP compress rotated logs - default - false
    89  //
    90  // Default values provide backward-compatibility with golang/glog. If compression is used,
    91  // all files except the current one are compressed with GZIP.
    92  //
    93  // Rotation works like this:
    94  //  - if MaxSize or RotationInterval is reached, and file size is > MinSize,
    95  //    current file became old file, and new file is created as a current log file
    96  //  - all log files older than MaxAge are removed
    97  //  - if compression is enabled, the old file is compressed
    98  //  - size of all log files in log_dir is recalculated (to handle external removals of files, etc)
    99  //  - oldest log files are removed until total size of log files doesn't exceed  MaxTotalSize-MaxSize
   100  // For sanity, this action is executed only when current file is needs to be rotated
   101  //
   102  package glog
   103  
   104  import (
   105  	"bufio"
   106  	"bytes"
   107  	"compress/gzip"
   108  	"errors"
   109  	"fmt"
   110  	"io"
   111  	"io/ioutil"
   112  	stdLog "log"
   113  	"os"
   114  	"path/filepath"
   115  	"regexp"
   116  	"runtime"
   117  	"sort"
   118  	"strconv"
   119  	"strings"
   120  	"sync"
   121  	"sync/atomic"
   122  	"time"
   123  
   124  	"github.com/ethereumproject/go-ethereum/common"
   125  	"github.com/fatih/color"
   126  )
   127  
   128  // DefaultVerbosity establishes the default verbosity Level for
   129  // to-file (debug) logging.
   130  var DefaultVerbosity = 5
   131  
   132  // DefaultDisplay establishes the default verbosity Level for
   133  // display (stderr) logging.
   134  var DefaultDisplay = 3
   135  
   136  // DefaultToStdErr establishes the default bool toggling whether logging
   137  // should be directed ONLY to stderr.
   138  var DefaultToStdErr = false
   139  
   140  // DefaultAlsoToStdErr establishes the default bool toggling whether logging
   141  // should be written to BOTH file and stderr.
   142  var DefaultAlsoToStdErr = false
   143  
   144  // DefaultLogDirName establishes the default directory name for debug (V) logs.
   145  // Log files will be written inside this dir.
   146  // By default, this directory will be created if it does not exist within the context's chain directory, eg.
   147  // <datadir>/<chain>/log/.
   148  var DefaultLogDirName = "log"
   149  
   150  // MinSize is a minimum file size qualifying for rotation. This variable can be used
   151  // to avoid rotation of empty or almost emtpy files.
   152  var MinSize uint64
   153  
   154  // MaxTotalSize is a maximum size of all log files.
   155  var MaxTotalSize uint64
   156  
   157  // Interval is a type for rotation interval specification
   158  type Interval uint8
   159  
   160  // These constants identify the interval for log rotation.
   161  const (
   162  	Never Interval = iota
   163  	Hourly
   164  	Daily
   165  	Weekly
   166  	Monthly
   167  )
   168  
   169  func ParseInterval(str string) (Interval, error) {
   170  	mapping := map[string]Interval{
   171  		"never":   Never,
   172  		"hourly":  Hourly,
   173  		"daily":   Daily,
   174  		"weekly":  Weekly,
   175  		"monthly": Monthly,
   176  	}
   177  
   178  	interval, ok := mapping[strings.ToLower(str)]
   179  	if !ok {
   180  		return Never, fmt.Errorf("invalid interval value '%s'", str)
   181  	}
   182  	return interval, nil
   183  }
   184  
   185  // RotationInterval determines how often log rotation should take place
   186  var RotationInterval = Never
   187  
   188  // MaxAge defines the maximum age of the oldest log file. All log files older
   189  // than MaxAge will be removed.
   190  var MaxAge time.Duration
   191  
   192  // Compress determines whether to compress rotated logs with GZIP or not.
   193  var Compress bool
   194  
   195  // severity identifies the sort of log: info, warning etc. It also implements
   196  // the flag.Value interface. The -stderrthreshold flag is of type severity and
   197  // should be modified only through the flag.Value interface. The values match
   198  // the corresponding constants in C++.
   199  // Severity is determined by the method called upon receiver Verbose,
   200  // eg. glog.V(logger.Debug).Warnf("this log's severity is %v", warningLog)
   201  // eg. glog.V(logger.Error).Infof("This log's severity is %v", infoLog)
   202  type severity int32 // sync/atomic int32
   203  
   204  // These constants identify the log levels in order of increasing severity.
   205  // A message written to a high-severity log file is also written to each
   206  // lower-severity log file.
   207  const (
   208  	infoLog severity = iota
   209  	warningLog
   210  	errorLog
   211  	fatalLog
   212  	numSeverity = 4
   213  )
   214  
   215  const severityChar = "IWEF"
   216  
   217  const severityColorReset = "\x1b[0m"                                        // reset both foreground and background
   218  var severityColor = []string{"\x1b[2m", "\x1b[33m", "\x1b[31m", "\x1b[35m"} // info:dim warn:yellow, error:red, fatal:magenta
   219  
   220  var severityName = []string{
   221  	infoLog:    "INFO",
   222  	warningLog: "WARN",
   223  	errorLog:   "ERR ",
   224  	fatalLog:   "FAIL",
   225  }
   226  
   227  // these path prefixes are trimmed for display, but not when
   228  // matching vmodule filters.
   229  var trimPrefixes = []string{
   230  	"/github.com/ethereumproject/go-ethereum",
   231  	"/github.com/ethereumproject/ethash",
   232  }
   233  
   234  func trimToImportPath(file string) string {
   235  	if root := strings.LastIndex(file, "src/"); root != 0 {
   236  		file = file[root+3:]
   237  	}
   238  	return file
   239  }
   240  
   241  // SetV sets the global verbosity level
   242  func SetV(v int) {
   243  	logging.verbosity.set(Level(v))
   244  }
   245  
   246  func SetD(v int) {
   247  	display.verbosity.set(Level(v))
   248  }
   249  
   250  // SetToStderr sets the global output style
   251  func SetToStderr(toStderr bool) {
   252  	logging.mu.Lock()
   253  	logging.toStderr = toStderr
   254  	logging.mu.Unlock()
   255  }
   256  
   257  // SetAlsoToStderr sets global output option
   258  // for logging to both FS and stderr.
   259  func SetAlsoToStderr(to bool) {
   260  	logging.mu.Lock()
   261  
   262  	logging.alsoToStderr = to
   263  	logging.mu.Unlock()
   264  }
   265  
   266  // GetTraceLocation returns the global TraceLocation flag.
   267  func GetTraceLocation() *TraceLocation {
   268  	return &logging.traceLocation
   269  }
   270  
   271  // GetVModule returns the global verbosity pattern flag.
   272  func GetVModule() *moduleSpec {
   273  	return &logging.vmodule
   274  }
   275  
   276  // GetVerbosity returns the global verbosity level flag.
   277  func GetVerbosity() *Level {
   278  	return &logging.verbosity
   279  }
   280  
   281  func GetDisplayable() *Level {
   282  	return &display.verbosity
   283  }
   284  
   285  // get returns the value of the severity.
   286  func (s *severity) get() severity {
   287  	return severity(atomic.LoadInt32((*int32)(s)))
   288  }
   289  
   290  // set sets the value of the severity.
   291  func (s *severity) set(val severity) {
   292  	atomic.StoreInt32((*int32)(s), int32(val))
   293  }
   294  
   295  // String is part of the flag.Value interface.
   296  func (s *severity) String() string {
   297  	return strconv.FormatInt(int64(*s), 10)
   298  }
   299  
   300  // Get is part of the flag.Value interface.
   301  func (s *severity) Get() interface{} {
   302  	return *s
   303  }
   304  
   305  // Set is part of the flag.Value interface.
   306  func (s *severity) Set(value string) error {
   307  	var threshold severity
   308  	// Is it a known name?
   309  	if v, ok := severityByName(value); ok {
   310  		threshold = v
   311  	} else {
   312  		v, err := strconv.Atoi(value)
   313  		if err != nil {
   314  			return err
   315  		}
   316  		threshold = severity(v)
   317  	}
   318  	logging.stderrThreshold.set(threshold)
   319  	return nil
   320  }
   321  
   322  func severityByName(s string) (severity, bool) {
   323  	s = strings.ToUpper(s)
   324  	for i, name := range severityName {
   325  		if name == s {
   326  			return severity(i), true
   327  		}
   328  	}
   329  	return 0, false
   330  }
   331  
   332  // OutputStats tracks the number of output lines and bytes written.
   333  type OutputStats struct {
   334  	lines int64
   335  	bytes int64
   336  }
   337  
   338  // Lines returns the number of lines written.
   339  func (s *OutputStats) Lines() int64 {
   340  	return atomic.LoadInt64(&s.lines)
   341  }
   342  
   343  // Bytes returns the number of bytes written.
   344  func (s *OutputStats) Bytes() int64 {
   345  	return atomic.LoadInt64(&s.bytes)
   346  }
   347  
   348  // Stats tracks the number of lines of output and number of bytes
   349  // per severity level. Values must be read with atomic.LoadInt64.
   350  var Stats struct {
   351  	Info, Warning, Error OutputStats
   352  }
   353  
   354  var severityStats = [numSeverity]*OutputStats{
   355  	infoLog:    &Stats.Info,
   356  	warningLog: &Stats.Warning,
   357  	errorLog:   &Stats.Error,
   358  }
   359  
   360  // Level is exported because it appears in the arguments to V and is
   361  // the type of the v flag, which can be set programmatically.
   362  // It's a distinct type because we want to discriminate it from logType.
   363  // Variables of type level are only changed under logging.mu.
   364  // The -v flag is read only with atomic ops, so the state of the logging
   365  // module is consistent.
   366  
   367  // Level is treated as a sync/atomic int32.
   368  
   369  // Level specifies a level of verbosity for V logs. *Level implements
   370  // flag.Value; the -v flag is of type Level and should be modified
   371  // only through the flag.Value interface.
   372  type Level int32
   373  
   374  // get returns the value of the Level.
   375  func (l *Level) get() Level {
   376  	return Level(atomic.LoadInt32((*int32)(l)))
   377  }
   378  
   379  // set sets the value of the Level.
   380  func (l *Level) set(val Level) {
   381  	atomic.StoreInt32((*int32)(l), int32(val))
   382  }
   383  
   384  // String is part of the flag.Value interface.
   385  func (l *Level) String() string {
   386  	return strconv.FormatInt(int64(*l), 10)
   387  }
   388  
   389  // Get is part of the flag.Value interface.
   390  func (l *Level) Get() interface{} {
   391  	return *l
   392  }
   393  
   394  // Set is part of the flag.Value interface.
   395  func (l *Level) Set(value string) error {
   396  	v, err := strconv.Atoi(value)
   397  	if err != nil {
   398  		return err
   399  	}
   400  	logging.mu.Lock()
   401  	defer logging.mu.Unlock()
   402  	logging.setVState(Level(v), logging.vmodule.filter, false)
   403  	return nil
   404  }
   405  
   406  // moduleSpec represents the setting of the -vmodule flag.
   407  type moduleSpec struct {
   408  	filter []modulePat
   409  }
   410  
   411  // modulePat contains a filter for the -vmodule flag.
   412  // It holds a verbosity level and a file pattern to match.
   413  type modulePat struct {
   414  	pattern *regexp.Regexp
   415  	level   Level
   416  }
   417  
   418  func (m *moduleSpec) String() string {
   419  	// Lock because the type is not atomic. TODO: clean this up.
   420  	logging.mu.Lock()
   421  	defer logging.mu.Unlock()
   422  	var b bytes.Buffer
   423  	for i, f := range m.filter {
   424  		if i > 0 {
   425  			b.WriteRune(',')
   426  		}
   427  		fmt.Fprintf(&b, "%s=%d", f.pattern, f.level)
   428  	}
   429  	return b.String()
   430  }
   431  
   432  // Get is part of the (Go 1.2)  flag.Getter interface. It always returns nil for this flag type since the
   433  // struct is not exported.
   434  func (m *moduleSpec) Get() interface{} {
   435  	return nil
   436  }
   437  
   438  var errVmoduleSyntax = errors.New("syntax error: expect comma-separated list of filename=N")
   439  
   440  // Syntax: -vmodule=recordio=2,file=1,gfs*=3
   441  func (m *moduleSpec) Set(value string) error {
   442  	var filter []modulePat
   443  	for _, pat := range strings.Split(value, ",") {
   444  		if len(pat) == 0 {
   445  			// Empty strings such as from a trailing comma can be ignored.
   446  			continue
   447  		}
   448  		patLev := strings.Split(pat, "=")
   449  		if len(patLev) != 2 || len(patLev[0]) == 0 || len(patLev[1]) == 0 {
   450  			return errVmoduleSyntax
   451  		}
   452  		pattern := patLev[0]
   453  		v, err := strconv.Atoi(patLev[1])
   454  		if err != nil {
   455  			return errors.New("syntax error: expect comma-separated list of filename=N")
   456  		}
   457  		if v < 0 {
   458  			return errors.New("negative value for vmodule level")
   459  		}
   460  		if v == 0 {
   461  			continue // Ignore. It's harmless but no point in paying the overhead.
   462  		}
   463  		// TODO: check syntax of filter?
   464  		re, _ := compileModulePattern(pattern)
   465  		filter = append(filter, modulePat{re, Level(v)})
   466  	}
   467  	logging.mu.Lock()
   468  	defer logging.mu.Unlock()
   469  	logging.setVState(logging.verbosity, filter, true)
   470  	return nil
   471  }
   472  
   473  // compiles a vmodule pattern to a regular expression.
   474  func compileModulePattern(pat string) (*regexp.Regexp, error) {
   475  	re := ".*"
   476  	for _, comp := range strings.Split(pat, "/") {
   477  		if comp == "*" {
   478  			re += "(/.*)?"
   479  		} else if comp != "" {
   480  			// TODO: maybe return error if comp contains *
   481  			re += "/" + regexp.QuoteMeta(comp)
   482  		}
   483  	}
   484  	if !strings.HasSuffix(pat, ".go") {
   485  		re += "/[^/]+\\.go"
   486  	}
   487  	return regexp.Compile(re + "$")
   488  }
   489  
   490  // traceLocation represents the setting of the -log_backtrace_at flag.
   491  type TraceLocation struct {
   492  	file string
   493  	line int
   494  }
   495  
   496  // isSet reports whether the trace location has been specified.
   497  // logging.mu is held.
   498  func (t *TraceLocation) isSet() bool {
   499  	return t.line > 0
   500  }
   501  
   502  // match reports whether the specified file and line matches the trace location.
   503  // The argument file name is the full path, not the basename specified in the flag.
   504  // logging.mu is held.
   505  func (t *TraceLocation) match(file string, line int) bool {
   506  	if t.line != line {
   507  		return false
   508  	}
   509  	if i := strings.LastIndex(file, "/"); i >= 0 {
   510  		file = file[i+1:]
   511  	}
   512  	return t.file == file
   513  }
   514  
   515  func (t *TraceLocation) String() string {
   516  	// Lock because the type is not atomic. TODO: clean this up.
   517  	logging.mu.Lock()
   518  	defer logging.mu.Unlock()
   519  	return fmt.Sprintf("%s:%d", t.file, t.line)
   520  }
   521  
   522  // Get is part of the (Go 1.2) flag.Getter interface. It always returns nil for this flag type since the
   523  // struct is not exported
   524  func (t *TraceLocation) Get() interface{} {
   525  	return nil
   526  }
   527  
   528  var errTraceSyntax = errors.New("syntax error: expect 'file.go:234'")
   529  
   530  // Syntax: -log_backtrace_at=gopherflakes.go:234
   531  // Note that unlike vmodule the file extension is included here.
   532  func (t *TraceLocation) Set(value string) error {
   533  	if value == "" {
   534  		// Unset.
   535  		logging.mu.Lock()
   536  		t.line = 0
   537  		t.file = ""
   538  		logging.mu.Unlock()
   539  		return nil
   540  	}
   541  
   542  	fields := strings.Split(value, ":")
   543  	if len(fields) != 2 {
   544  		return errTraceSyntax
   545  	}
   546  	file, line := fields[0], fields[1]
   547  	if !strings.Contains(file, ".") {
   548  		return errTraceSyntax
   549  	}
   550  	v, err := strconv.Atoi(line)
   551  	if err != nil {
   552  		return errTraceSyntax
   553  	}
   554  	if v <= 0 {
   555  		return errors.New("negative or zero value for level")
   556  	}
   557  	logging.mu.Lock()
   558  	defer logging.mu.Unlock()
   559  	t.line = v
   560  	t.file = file
   561  	return nil
   562  }
   563  
   564  // flushSyncWriter is the interface satisfied by logging destinations.
   565  type flushSyncWriter interface {
   566  	Flush() error
   567  	Sync() error
   568  	io.Writer
   569  }
   570  
   571  type logTName string
   572  
   573  const (
   574  	fileLog    logTName = "file"
   575  	displayLog logTName = "display"
   576  )
   577  
   578  // loggingT collects all the global state of the logging setup.
   579  type loggingT struct {
   580  	logTName
   581  	// Boolean flags. Not handled atomically because the flag.Value interface
   582  	// does not let us avoid the =true, and that shorthand is necessary for
   583  	// compatibility. TODO: does this matter enough to fix? Seems unlikely.
   584  	toStderr     bool // The -logtostderr flag.
   585  	alsoToStderr bool // The -alsologtostderr flag.
   586  
   587  	// Level flag. Handled atomically.
   588  	stderrThreshold severity // The -stderrthreshold flag.
   589  
   590  	// freeList is a list of byte buffers, maintained under freeListMu.
   591  	freeList *buffer
   592  	// freeListMu maintains the free list. It is separate from the main mutex
   593  	// so buffers can be grabbed and printed to without holding the main lock,
   594  	// for better parallelization.
   595  	freeListMu sync.Mutex
   596  
   597  	// mu protects the remaining elements of this structure and is
   598  	// used to synchronize logging.
   599  	mu sync.Mutex
   600  	// file holds writer for each of the log types.
   601  	file [numSeverity]flushSyncWriter
   602  	// pcs is used in V to avoid an allocation when computing the caller's PC.
   603  	pcs [1]uintptr
   604  	// vmap is a cache of the V Level for each V() call site, identified by PC.
   605  	// It is wiped whenever the vmodule flag changes state.
   606  	vmap map[uintptr]Level
   607  	// filterLength stores the length of the vmodule filter chain. If greater
   608  	// than zero, it means vmodule is enabled. It may be read safely
   609  	// using sync.LoadInt32, but is only modified under mu.
   610  	filterLength int32
   611  	// traceLocation is the state of the -log_backtrace_at flag.
   612  	traceLocation TraceLocation
   613  	// These flags are modified only under lock, although verbosity may be fetched
   614  	// safely using atomic.LoadInt32.
   615  	vmodule   moduleSpec // The state of the -vmodule flag.
   616  	verbosity Level      // V logging level, the value of the -v flag/
   617  
   618  	// severityTraceThreshold determines the minimum severity at which
   619  	// file traces will be logged in the header. See severity const iota above.
   620  	// Only severities at or above this number will be logged with a trace,
   621  	// eg. at severityTraceThreshold = 2, then only severities errorLog and fatalLog
   622  	// will log with traces.
   623  	severityTraceThreshold severity
   624  
   625  	// verbosityTraceThreshold determines the minimum verbosity at which
   626  	// file traces will be logged in the header.
   627  	// Only levels at or above this number will be logged with a trace,
   628  	// eg. at verbosityTraceThreshold = 5, then only verbosities Debug, Detail, and Ridiculousness
   629  	// will log with traces.
   630  	verbosityTraceThreshold Level
   631  }
   632  
   633  // buffer holds a byte Buffer for reuse. The zero value is ready for use.
   634  type buffer struct {
   635  	bytes.Buffer
   636  	tmp  [64]byte // temporary byte array for creating headers.
   637  	next *buffer
   638  }
   639  
   640  var logging loggingT
   641  var display loggingT
   642  
   643  func init() {
   644  	//flag.BoolVar(&logging.toStderr, "logtostderr", false, "log to standard error instead of files")
   645  	//flag.BoolVar(&logging.alsoToStderr, "alsologtostderr", false, "log to standard error as well as files")
   646  	//flag.Var(&logging.verbosity, "v", "log level for V logs")
   647  	//flag.Var(&logging.stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr")
   648  	//flag.Var(&logging.vmodule, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging")
   649  	//flag.Var(&logging.traceLocation, "log_backtrace_at", "when logging hits line file:N, emit a stack trace")
   650  
   651  	logging.logTName = fileLog
   652  	// Default stderrThreshold is ERROR.
   653  	// This makes V(logger.Error) logs print ALSO to stderr.
   654  	logging.stderrThreshold = errorLog
   655  
   656  	// Establish defaults for trace thresholds.
   657  	logging.verbosityTraceThreshold.set(0)
   658  	logging.severityTraceThreshold.set(2)
   659  
   660  	// Default for verbosity.
   661  	logging.setVState(Level(DefaultVerbosity), nil, false)
   662  	go logging.flushDaemon()
   663  
   664  	display.logTName = displayLog
   665  	// Renders anything at or below (Warn...) level Info to stderr, which
   666  	// is set by default anyway.
   667  	display.stderrThreshold = infoLog
   668  
   669  	// toStderr makes it ONLY print to stderr, not to file
   670  	display.toStderr = true
   671  
   672  	// Should never reach... unless we get real fancy with D(levels)
   673  	display.verbosityTraceThreshold.set(5)
   674  	// Only includes traces for severity=fatal logs for display.
   675  	// This should never be reached; fatal logs should ALWAYS be logged to file,
   676  	// and they will also be written to stderr (anything Error and above is).
   677  	// Keep in mind severities are "upside-down" from verbosities; so here 3=error, 4=fatal, and 0=info
   678  	// and that here severity>=3 will meet the threshold.
   679  	display.severityTraceThreshold.set(2)
   680  	// Set display verbosity default Info. So it will render
   681  	// all Fatal, Error, Warn, and Info log levels.
   682  	// Please don't use Fatal for display; again, Fatal logs should only go through file logging
   683  	// (they will be printed to stderr anyway).
   684  	display.setVState(Level(DefaultDisplay), nil, false)
   685  	go display.flushDaemon()
   686  }
   687  
   688  // Flush flushes all pending log I/O.
   689  func Flush() {
   690  	logging.lockAndFlushAll()
   691  	display.lockAndFlushAll()
   692  }
   693  
   694  // traceThreshold determines the arbitrary level for log lines to be printed
   695  // with caller trace information in the header.
   696  func (l *loggingT) traceThreshold(s severity) bool {
   697  	return s >= l.severityTraceThreshold || l.verbosity >= l.verbosityTraceThreshold
   698  }
   699  
   700  // GetVTraceThreshold gets the current verbosity trace threshold for logging.
   701  func GetVTraceThreshold() *Level {
   702  	return &logging.verbosityTraceThreshold
   703  }
   704  
   705  // SetVTraceThreshold sets the current verbosity trace threshold for logging.
   706  func SetVTraceThreshold(v int) {
   707  	logging.mu.Lock()
   708  	defer logging.mu.Unlock()
   709  
   710  	l := logging.verbosity.get()
   711  	logging.verbosity.set(0)
   712  	logging.verbosityTraceThreshold.set(Level(v))
   713  	logging.verbosity.set(l)
   714  }
   715  
   716  // setVState sets a consistent state for V logging.
   717  // l.mu is held.
   718  func (l *loggingT) setVState(verbosity Level, filter []modulePat, setFilter bool) {
   719  	// Turn verbosity off so V will not fire while we are in transition.
   720  	l.verbosity.set(0)
   721  	// Ditto for filter length.
   722  	atomic.StoreInt32(&l.filterLength, 0)
   723  
   724  	// Set the new filters and wipe the pc->Level map if the filter has changed.
   725  	if setFilter {
   726  		l.vmodule.filter = filter
   727  		l.vmap = make(map[uintptr]Level)
   728  	}
   729  
   730  	// Things are consistent now, so enable filtering and verbosity.
   731  	// They are enabled in order opposite to that in V.
   732  	atomic.StoreInt32(&l.filterLength, int32(len(filter)))
   733  	l.verbosity.set(verbosity)
   734  }
   735  
   736  // getBuffer returns a new, ready-to-use buffer.
   737  func (l *loggingT) getBuffer() *buffer {
   738  	l.freeListMu.Lock()
   739  	b := l.freeList
   740  	if b != nil {
   741  		l.freeList = b.next
   742  	}
   743  	l.freeListMu.Unlock()
   744  	if b == nil {
   745  		b = new(buffer)
   746  	} else {
   747  		b.next = nil
   748  		b.Reset()
   749  	}
   750  	return b
   751  }
   752  
   753  // putBuffer returns a buffer to the free list.
   754  func (l *loggingT) putBuffer(b *buffer) {
   755  	if b.Len() >= 256 {
   756  		// Let big buffers die a natural death.
   757  		return
   758  	}
   759  	l.freeListMu.Lock()
   760  	b.next = l.freeList
   761  	l.freeList = b
   762  	l.freeListMu.Unlock()
   763  }
   764  
   765  var timeNow = time.Now // Stubbed out for testing.
   766  
   767  /*
   768  header formats a log header as defined by the C++ implementation.
   769  It returns a buffer containing the formatted header and the user's file and line number.
   770  The depth specifies how many stack frames above lives the source line to be identified in the log message.
   771  
   772  Log lines have this form:
   773  	Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg...
   774  where the fields are defined as follows:
   775  	L                A single character, representing the log level (eg 'I' for INFO)
   776  	mm               The month (zero padded; ie May is '05')
   777  	dd               The day (zero padded)
   778  	hh:mm:ss.uuuuuu  Time in hours, minutes and fractional seconds
   779  	threadid         The space-padded thread ID as returned by GetTID()
   780  	file             The file name
   781  	line             The line number
   782  	msg              The user-supplied message
   783  */
   784  func (l *loggingT) header(s severity, depth int) (*buffer, string, int) {
   785  	_, file, line, ok := runtime.Caller(3 + depth)
   786  	if !ok {
   787  		file = "???"
   788  		line = 1
   789  	} else {
   790  		file = trimToImportPath(file)
   791  		for _, p := range trimPrefixes {
   792  			if strings.HasPrefix(file, p) {
   793  				file = file[len(p):]
   794  				break
   795  			}
   796  		}
   797  		file = file[1:] // drop '/'
   798  	}
   799  	return l.formatHeader(s, file, line), file, line
   800  }
   801  
   802  // formatHeader formats a log header using the provided file name and line number.
   803  func (l *loggingT) formatHeader(s severity, file string, line int) *buffer {
   804  	now := timeNow()
   805  	if line < 0 {
   806  		line = 0 // not a real line number, but acceptable to someDigits
   807  	}
   808  	if s > fatalLog {
   809  		s = infoLog // for safety.
   810  	}
   811  	buf := l.getBuffer()
   812  
   813  	// Avoid Fprintf, for speed. The format is so simple that we can do it quickly by hand.
   814  	// It's worth about 3X. Fprintf is hard.
   815  	year, month, day := now.Date()
   816  	hour, minute, second := now.Clock()
   817  	// Lmmdd hh:mm:ss.uuuuuu threadid file:line]
   818  
   819  	//buf.nDigits(8, 0, severityColor[s],'')
   820  
   821  	// If to-file (debuggable) logs.
   822  	if l.logTName == fileLog {
   823  		buf.tmp[0] = severityChar[s]
   824  		buf.Write(buf.tmp[:1])
   825  		buf.twoDigits(0, int(month))
   826  		buf.twoDigits(2, day)
   827  		buf.tmp[4] = ' '
   828  		buf.twoDigits(5, hour)
   829  		buf.tmp[7] = ':'
   830  		buf.twoDigits(8, minute)
   831  		buf.tmp[10] = ':'
   832  		buf.twoDigits(11, second)
   833  		// Only keep nanoseconds for file logs
   834  		buf.tmp[13] = '.'
   835  		buf.nDigits(6, 14, now.Nanosecond()/1000, '0')
   836  		buf.Write(buf.tmp[:20])
   837  		buf.WriteString(" ")
   838  
   839  		if l.traceThreshold(s) {
   840  			buf.WriteString(file)
   841  			buf.tmp[0] = ':'
   842  			n := buf.someDigits(1, line)
   843  			buf.tmp[n+1] = ']'
   844  			buf.tmp[n+2] = ' '
   845  			buf.Write(buf.tmp[:n+3])
   846  		}
   847  	} else {
   848  		// Write dim.
   849  		buf.WriteString(severityColor[infoLog])
   850  
   851  		buf.nDigits(4, 0, year, '_')
   852  		buf.nDigits(4, 0, year, '_')
   853  		buf.tmp[4] = '-'
   854  		buf.twoDigits(5, int(month))
   855  		buf.tmp[7] = '-'
   856  		buf.twoDigits(8, day)
   857  		buf.tmp[10] = ' '
   858  		buf.twoDigits(11, hour)
   859  		buf.tmp[13] = ':'
   860  		buf.twoDigits(14, minute)
   861  		buf.tmp[16] = ':'
   862  		buf.twoDigits(17, second)
   863  		buf.Write(buf.tmp[:19])
   864  
   865  		buf.WriteString(severityColorReset + " ")
   866  		if l.traceThreshold(s) {
   867  			buf.WriteString(severityColor[s])
   868  			buf.Write([]byte{'['})
   869  			buf.WriteString(severityName[s])
   870  			buf.Write([]byte{']'})
   871  			buf.WriteString(severityColorReset)
   872  			buf.Write([]byte{' '})
   873  		}
   874  	}
   875  
   876  	return buf
   877  }
   878  
   879  // Some custom tiny helper functions to print the log header efficiently.
   880  
   881  const digits = "0123456789"
   882  
   883  // twoDigits formats a zero-prefixed two-digit integer at buf.tmp[i].
   884  func (buf *buffer) twoDigits(i, d int) {
   885  	buf.tmp[i+1] = digits[d%10]
   886  	d /= 10
   887  	buf.tmp[i] = digits[d%10]
   888  }
   889  
   890  // nDigits formats an n-digit integer at buf.tmp[i],
   891  // padding with pad on the left.
   892  // It assumes d >= 0.
   893  func (buf *buffer) nDigits(n, i, d int, pad byte) {
   894  	j := n - 1
   895  	for ; j >= 0 && d > 0; j-- {
   896  		buf.tmp[i+j] = digits[d%10]
   897  		d /= 10
   898  	}
   899  	for ; j >= 0; j-- {
   900  		buf.tmp[i+j] = pad
   901  	}
   902  }
   903  
   904  // someDigits formats a zero-prefixed variable-width integer at buf.tmp[i].
   905  func (buf *buffer) someDigits(i, d int) int {
   906  	// Print into the top, then copy down. We know there's space for at least
   907  	// a 10-digit number.
   908  	j := len(buf.tmp)
   909  	for {
   910  		j--
   911  		buf.tmp[j] = digits[d%10]
   912  		d /= 10
   913  		if d == 0 {
   914  			break
   915  		}
   916  	}
   917  	return copy(buf.tmp[i:], buf.tmp[j:])
   918  }
   919  
   920  func (l *loggingT) println(s severity, args ...interface{}) {
   921  	buf, file, line := l.header(s, 0)
   922  	fmt.Fprintln(buf, args...)
   923  	l.output(s, buf, file, line, false)
   924  }
   925  
   926  func (l *loggingT) print(s severity, args ...interface{}) {
   927  	l.printDepth(s, 1, args...)
   928  }
   929  
   930  func (l *loggingT) printDepth(s severity, depth int, args ...interface{}) {
   931  	buf, file, line := l.header(s, depth)
   932  	fmt.Fprint(buf, args...)
   933  	if buf.Bytes()[buf.Len()-1] != '\n' {
   934  		buf.WriteByte('\n')
   935  	}
   936  	l.output(s, buf, file, line, false)
   937  }
   938  
   939  func (l *loggingT) printfmt(s severity, format string, args ...interface{}) {
   940  	buf, file, line := l.header(s, 0)
   941  	fmt.Fprintf(buf, format, args...)
   942  	if buf.Bytes()[buf.Len()-1] != '\n' {
   943  		buf.WriteByte('\n')
   944  	}
   945  	l.output(s, buf, file, line, false)
   946  }
   947  
   948  // printWithFileLine behaves like print but uses the provided file and line number.  If
   949  // alsoLogToStderr is true, the log message always appears on standard error; it
   950  // will also appear in the log file unless --logtostderr is set.
   951  func (l *loggingT) printWithFileLine(s severity, file string, line int, alsoToStderr bool, args ...interface{}) {
   952  	buf := l.formatHeader(s, file, line)
   953  	fmt.Fprint(buf, args...)
   954  	if buf.Bytes()[buf.Len()-1] != '\n' {
   955  		buf.WriteByte('\n')
   956  	}
   957  	l.output(s, buf, file, line, alsoToStderr)
   958  }
   959  
   960  // output writes the data to the log files and releases the buffer.
   961  func (l *loggingT) output(s severity, buf *buffer, file string, line int, alsoToStderr bool) {
   962  	l.mu.Lock()
   963  	if l.traceLocation.isSet() {
   964  		if l.traceLocation.match(file, line) {
   965  			buf.Write(stacks(false))
   966  		}
   967  	}
   968  	data := buf.Bytes()
   969  	if l.toStderr {
   970  		color.Error.Write(data)
   971  	} else {
   972  		if alsoToStderr || l.alsoToStderr || s >= l.stderrThreshold.get() {
   973  			color.Error.Write(data)
   974  		}
   975  		if l.file[s] == nil {
   976  			if err := l.createFiles(s); err != nil {
   977  				color.Error.Write(data) // Make sure the message appears somewhere.
   978  				l.exit(err)
   979  			}
   980  		}
   981  		switch s {
   982  		case fatalLog:
   983  			l.file[fatalLog].Write(data)
   984  			fallthrough
   985  		case errorLog:
   986  			l.file[errorLog].Write(data)
   987  			fallthrough
   988  		case warningLog:
   989  			l.file[warningLog].Write(data)
   990  			fallthrough
   991  		case infoLog:
   992  			l.file[infoLog].Write(data)
   993  		}
   994  	}
   995  	if s == fatalLog {
   996  		// If we got here via Exit rather than Fatal, print no stacks.
   997  		if atomic.LoadUint32(&fatalNoStacks) > 0 {
   998  			l.mu.Unlock()
   999  			timeoutFlush(10 * time.Second)
  1000  			os.Exit(1)
  1001  		}
  1002  		// Dump all goroutine stacks before exiting.
  1003  		// First, make sure we see the trace for the current goroutine on standard error.
  1004  		// If -logtostderr has been specified, the loop below will do that anyway
  1005  		// as the first stack in the full dump.
  1006  		if !l.toStderr {
  1007  			color.Error.Write(stacks(false))
  1008  		}
  1009  		// Write the stack trace for all goroutines to the files.
  1010  		trace := stacks(true)
  1011  		logExitFunc = func(error) {} // If we get a write error, we'll still exit below.
  1012  		for log := fatalLog; log >= infoLog; log-- {
  1013  			if f := l.file[log]; f != nil { // Can be nil if -logtostderr is set.
  1014  				f.Write(trace)
  1015  			}
  1016  		}
  1017  		l.mu.Unlock()
  1018  		timeoutFlush(10 * time.Second)
  1019  		os.Exit(255) // C++ uses -1, which is silly because it's anded with 255 anyway.
  1020  	}
  1021  	l.putBuffer(buf)
  1022  	l.mu.Unlock()
  1023  	if stats := severityStats[s]; stats != nil {
  1024  		atomic.AddInt64(&stats.lines, 1)
  1025  		atomic.AddInt64(&stats.bytes, int64(len(data)))
  1026  	}
  1027  }
  1028  
  1029  // timeoutFlush calls Flush and returns when it completes or after timeout
  1030  // elapses, whichever happens first.  This is needed because the hooks invoked
  1031  // by Flush may deadlock when glog.Fatal is called from a hook that holds
  1032  // a lock.
  1033  func timeoutFlush(timeout time.Duration) {
  1034  	done := make(chan bool, 1)
  1035  	go func() {
  1036  		Flush() // calls logging.lockAndFlushAll()
  1037  		done <- true
  1038  	}()
  1039  	select {
  1040  	case <-done:
  1041  	case <-time.After(timeout):
  1042  		fmt.Fprintln(color.Error, "glog: Flush took longer than", timeout)
  1043  	}
  1044  }
  1045  
  1046  // stacks is a wrapper for runtime.Stack that attempts to recover the data for all goroutines.
  1047  func stacks(all bool) []byte {
  1048  	// We don't know how big the traces are, so grow a few times if they don't fit. Start large, though.
  1049  	n := 10000
  1050  	if all {
  1051  		n = 100000
  1052  	}
  1053  	var trace []byte
  1054  	for i := 0; i < 5; i++ {
  1055  		trace = make([]byte, n)
  1056  		nbytes := runtime.Stack(trace, all)
  1057  		if nbytes < len(trace) {
  1058  			return trace[:nbytes]
  1059  		}
  1060  		n *= 2
  1061  	}
  1062  	return trace
  1063  }
  1064  
  1065  // logExitFunc provides a simple mechanism to override the default behavior
  1066  // of exiting on error. Used in testing and to guarantee we reach a required exit
  1067  // for fatal logs. Instead, exit could be a function rather than a method but that
  1068  // would make its use clumsier.
  1069  var logExitFunc func(error)
  1070  
  1071  // exit is called if there is trouble creating or writing log files.
  1072  // It flushes the logs and exits the program; there's no point in hanging around.
  1073  // l.mu is held.
  1074  func (l *loggingT) exit(err error) {
  1075  	fmt.Fprintf(color.Error, "log: exiting because of error: %s\n", err)
  1076  	// If logExitFunc is set, we do that instead of exiting.
  1077  	if logExitFunc != nil {
  1078  		logExitFunc(err)
  1079  		return
  1080  	}
  1081  	l.flushAll()
  1082  	os.Exit(2)
  1083  }
  1084  
  1085  // syncBuffer joins a bufio.Writer to its underlying file, providing access to the
  1086  // file's Sync method and providing a wrapper for the Write method that provides log
  1087  // file rotation. There are conflicting methods, so the file cannot be embedded.
  1088  // l.mu is held for all its methods.
  1089  type syncBuffer struct {
  1090  	logger *loggingT
  1091  	*bufio.Writer
  1092  	file   *os.File
  1093  	time   time.Time
  1094  	sev    severity
  1095  	nbytes uint64 // The number of bytes written to this file
  1096  }
  1097  
  1098  func (sb *syncBuffer) Sync() error {
  1099  	return sb.file.Sync()
  1100  }
  1101  
  1102  func (sb *syncBuffer) Write(p []byte) (n int, err error) {
  1103  	now := time.Now()
  1104  	if sb.shouldRotate(len(p), now) {
  1105  		if err := sb.rotateCurrent(now); err != nil {
  1106  			sb.logger.exit(err)
  1107  		}
  1108  		go sb.rotateOld(now)
  1109  	}
  1110  	n, err = sb.Writer.Write(p)
  1111  	sb.nbytes += uint64(n)
  1112  	if err != nil {
  1113  		sb.logger.exit(err)
  1114  	}
  1115  	return
  1116  }
  1117  
  1118  // shouldRotate checks if we need to rotate the current log file
  1119  func (sb *syncBuffer) shouldRotate(len int, now time.Time) bool {
  1120  	newLen := sb.nbytes + uint64(len)
  1121  	if newLen <= MinSize {
  1122  		return false
  1123  	} else if MaxSize > 0 && newLen >= MaxSize {
  1124  		return true
  1125  	}
  1126  
  1127  	switch RotationInterval {
  1128  	case Never:
  1129  		return false
  1130  	case Hourly:
  1131  		return sb.time.Hour() != now.Hour()
  1132  	case Daily:
  1133  		return sb.time.Day() != now.Day()
  1134  	case Weekly:
  1135  		yearLog, weekLog := sb.time.ISOWeek()
  1136  		yearNow, weekNow := now.ISOWeek()
  1137  		return !(yearLog == yearNow && weekLog == weekNow)
  1138  	case Monthly:
  1139  		return sb.time.Month() != now.Month()
  1140  	}
  1141  	return false
  1142  }
  1143  
  1144  // rotateCurrent closes the syncBuffer's file and starts a new one.
  1145  func (sb *syncBuffer) rotateCurrent(now time.Time) error {
  1146  	if sb.file != nil {
  1147  		sb.Flush()
  1148  		sb.file.Close()
  1149  	}
  1150  	var err error
  1151  	sb.file, _, err = create(severityName[sb.sev], now)
  1152  	sb.nbytes = 0
  1153  	sb.time = time.Now()
  1154  	if err != nil {
  1155  		return err
  1156  	}
  1157  
  1158  	sb.Writer = bufio.NewWriterSize(sb.file, bufferSize)
  1159  
  1160  	// Write header.
  1161  	var buf bytes.Buffer
  1162  	fmt.Fprintf(&buf, "Log file created at: %s\n", now.Format("2006/01/02 15:04:05"))
  1163  	fmt.Fprintf(&buf, "Binary: Built with %s %s for %s/%s\n", runtime.Compiler, runtime.Version(), runtime.GOOS, runtime.GOARCH)
  1164  	fmt.Fprintf(&buf, "Context: %s\n", common.GetClientSessionIdentity().String())
  1165  	fmt.Fprintf(&buf, "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg\n")
  1166  	n, err := sb.file.Write(buf.Bytes())
  1167  	sb.nbytes += uint64(n)
  1168  	return err
  1169  }
  1170  
  1171  // converts plain log file to gzipped log file. New file is created
  1172  func gzipFile(name string) error {
  1173  	gzipped, err := os.Create(name + ".gz")
  1174  	defer gzipped.Close()
  1175  	if err != nil {
  1176  		return err
  1177  	}
  1178  	writer := bufio.NewWriter(gzipped)
  1179  	gzipWriter := gzip.NewWriter(writer)
  1180  
  1181  	plain, err := os.Open(name)
  1182  	if err != nil {
  1183  		return err
  1184  	}
  1185  	reader := bufio.NewReader(plain)
  1186  
  1187  	// copy from plain text file to gzipped output
  1188  	_, err = io.Copy(gzipWriter, reader)
  1189  	_ = plain.Close()
  1190  	if err != nil {
  1191  		return err
  1192  	}
  1193  	if err = gzipWriter.Close(); err != nil {
  1194  		return err
  1195  	}
  1196  	if err = writer.Flush(); err != nil {
  1197  		return err
  1198  	}
  1199  	if err = gzipped.Sync(); err != nil {
  1200  		return err
  1201  	}
  1202  	if err = gzipped.Close(); err != nil {
  1203  		return err
  1204  	}
  1205  
  1206  	return os.Remove(name)
  1207  }
  1208  
  1209  var rotationTime int64
  1210  
  1211  func (sb *syncBuffer) rotateOld(now time.Time) {
  1212  	nanos := now.UnixNano()
  1213  	if atomic.CompareAndSwapInt64(&rotationTime, 0, nanos) {
  1214  		logs, err := getLogFiles()
  1215  		if err != nil {
  1216  			Fatal(err)
  1217  		}
  1218  
  1219  		logs = sb.excludeActive(logs)
  1220  
  1221  		logs, err = removeOutdated(logs, now)
  1222  		if err != nil {
  1223  			Fatal(err)
  1224  		}
  1225  
  1226  		logs, err = compressOrphans(logs)
  1227  		if err != nil {
  1228  			Fatal(err)
  1229  		}
  1230  
  1231  		if MaxTotalSize > MaxSize {
  1232  			totalSize := getTotalSize(logs)
  1233  			for i := 0; i < len(logs) && totalSize > MaxTotalSize-MaxSize; i++ {
  1234  				err := os.Remove(filepath.Join(logs[i].dir, logs[i].name))
  1235  				if err != nil {
  1236  					Fatal(err)
  1237  				}
  1238  				totalSize -= logs[i].size
  1239  			}
  1240  		}
  1241  
  1242  		if current := atomic.SwapInt64(&rotationTime, 0); current > nanos {
  1243  			go sb.rotateOld(time.Unix(0, current))
  1244  		}
  1245  	} else {
  1246  		atomic.StoreInt64(&rotationTime, nanos)
  1247  	}
  1248  }
  1249  
  1250  type logFile struct {
  1251  	dir       string
  1252  	name      string
  1253  	size      uint64
  1254  	timestamp string
  1255  }
  1256  
  1257  // getLogFiles returns log files, ordered from oldest to newest
  1258  func getLogFiles() (logFiles []logFile, err error) {
  1259  	prefix := fmt.Sprintf("%s.%s.%s.log.", program, host, userName)
  1260  	for _, logDir := range logDirs {
  1261  		files, err := ioutil.ReadDir(logDir)
  1262  		if err == nil {
  1263  			files = filterLogFiles(files, prefix)
  1264  			for _, file := range files {
  1265  				logFiles = append(logFiles, logFile{
  1266  					dir:       logDir,
  1267  					name:      file.Name(),
  1268  					size:      uint64(file.Size()),
  1269  					timestamp: extractTimestamp(file.Name(), prefix),
  1270  				})
  1271  			}
  1272  			sort.Slice(logFiles, func(i, j int) bool {
  1273  				return logFiles[i].timestamp < logFiles[j].timestamp
  1274  			})
  1275  			return logFiles, nil
  1276  		}
  1277  	}
  1278  	return nil, errors.New("log: no log dirs")
  1279  }
  1280  
  1281  func (sb *syncBuffer) excludeActive(logs []logFile) []logFile {
  1282  	filtered := logs[:0]
  1283  	current := sb.getCurrentLogs()
  1284  	for _, log := range logs {
  1285  		active := false
  1286  		fullName := filepath.Join(log.dir, log.name)
  1287  		for _, latest := range current {
  1288  			if fullName == latest {
  1289  				active = true
  1290  			}
  1291  		}
  1292  		if !active {
  1293  			filtered = append(filtered, log)
  1294  		}
  1295  	}
  1296  	return filtered
  1297  }
  1298  
  1299  // getCurrentLogs returns list of log files currently in use by the syncBuffer
  1300  func (sb *syncBuffer) getCurrentLogs() (logs []string) {
  1301  	if sb.logger == nil {
  1302  		return nil
  1303  	}
  1304  	for _, buffer := range sb.logger.file {
  1305  		if buffer != nil && buffer.(*syncBuffer).file != nil {
  1306  			path, err := filepath.Abs(buffer.(*syncBuffer).file.Name())
  1307  			if err == nil {
  1308  				logs = append(logs, path)
  1309  			}
  1310  		}
  1311  	}
  1312  	return logs
  1313  }
  1314  
  1315  func extractTimestamp(logFile, prefix string) string {
  1316  	if len(logFile) <= len(prefix) {
  1317  		return ""
  1318  	}
  1319  	splits := strings.SplitN(logFile[len(prefix):], ".", 3)
  1320  	if len(splits) == 3 {
  1321  		return splits[1]
  1322  	} else {
  1323  		return ""
  1324  	}
  1325  }
  1326  
  1327  func filterLogFiles(files []os.FileInfo, prefix string) []os.FileInfo {
  1328  	filtered := files[:0]
  1329  	for _, file := range files {
  1330  		if !file.IsDir() && strings.HasPrefix(file.Name(), prefix) {
  1331  			filtered = append(filtered, file)
  1332  		}
  1333  	}
  1334  	return filtered
  1335  }
  1336  
  1337  func removeOutdated(logs []logFile, now time.Time) ([]logFile, error) {
  1338  	if MaxAge == 0 {
  1339  		return logs, nil
  1340  	}
  1341  	t := now.Add(-1 * MaxAge)
  1342  	timestamp := fmt.Sprintf("%04d%02d%02d-%02d%02d%02d",
  1343  		t.Year(),
  1344  		t.Month(),
  1345  		t.Day(),
  1346  		t.Hour(),
  1347  		t.Minute(),
  1348  		t.Second(),
  1349  	)
  1350  
  1351  	remaining := logs[:0]
  1352  	for _, log := range logs {
  1353  		if log.timestamp <= timestamp {
  1354  			if err := os.Remove(filepath.Join(log.dir, log.name)); err != nil {
  1355  				return nil, err
  1356  			}
  1357  		} else {
  1358  			remaining = append(remaining, log)
  1359  		}
  1360  	}
  1361  	return remaining, nil
  1362  }
  1363  
  1364  // compress all uncompressed log files, except the currently used log file
  1365  func compressOrphans(logs []logFile) ([]logFile, error) {
  1366  	for i, log := range logs {
  1367  		fullName := filepath.Join(log.dir, log.name)
  1368  		if !strings.HasSuffix(log.name, ".gz") {
  1369  			if err := gzipFile(fullName); err != nil {
  1370  				return nil, err
  1371  			}
  1372  			logs[i].name += ".gz"
  1373  		}
  1374  	}
  1375  	return logs, nil
  1376  }
  1377  
  1378  func getTotalSize(logs []logFile) (size uint64) {
  1379  	for _, log := range logs {
  1380  		size += log.size
  1381  	}
  1382  	return
  1383  }
  1384  
  1385  // bufferSize sizes the buffer associated with each log file. It's large
  1386  // so that log records can accumulate without the logging thread blocking
  1387  // on disk I/O. The flushDaemon will block instead.
  1388  const bufferSize = 256 * 1024
  1389  
  1390  // createFiles creates all the log files for severity from sev down to infoLog.
  1391  // l.mu is held.
  1392  func (l *loggingT) createFiles(sev severity) error {
  1393  	now := time.Now()
  1394  	// Files are created in decreasing severity order, so as soon as we find one
  1395  	// has already been created, we can stop.
  1396  	for s := sev; s >= infoLog && l.file[s] == nil; s-- {
  1397  		sb := &syncBuffer{
  1398  			logger: l,
  1399  			sev:    s,
  1400  		}
  1401  		if err := sb.rotateCurrent(now); err != nil {
  1402  			return err
  1403  		}
  1404  		l.file[s] = sb
  1405  	}
  1406  	return nil
  1407  }
  1408  
  1409  const flushInterval = 5 * time.Second
  1410  
  1411  // flushDaemon periodically flushes the log file buffers.
  1412  func (l *loggingT) flushDaemon() {
  1413  	for range time.NewTicker(flushInterval).C {
  1414  		l.lockAndFlushAll()
  1415  	}
  1416  }
  1417  
  1418  // lockAndFlushAll is like flushAll but locks l.mu first.
  1419  func (l *loggingT) lockAndFlushAll() {
  1420  	l.mu.Lock()
  1421  	l.flushAll()
  1422  	l.mu.Unlock()
  1423  }
  1424  
  1425  // flushAll flushes all the logs and attempts to "sync" their data to disk.
  1426  // l.mu is held.
  1427  func (l *loggingT) flushAll() {
  1428  	// Flush from fatal down, in case there's trouble flushing.
  1429  	for s := fatalLog; s >= infoLog; s-- {
  1430  		file := l.file[s]
  1431  		if file != nil {
  1432  			// if e := file.Flush(); e != nil {
  1433  			// 	stdLog.Fatalln(e)
  1434  			// }
  1435  			// if e := file.Sync(); e != nil {
  1436  			// 	stdLog.Fatalln(e)
  1437  			// }
  1438  			file.Flush() // ignore error
  1439  			file.Sync()  // ignore error
  1440  		}
  1441  	}
  1442  }
  1443  
  1444  // CopyStandardLogTo arranges for messages written to the Go "log" package's
  1445  // default logs to also appear in the Google logs for the named and lower
  1446  // severities.  Subsequent changes to the standard log's default output location
  1447  // or format may break this behavior.
  1448  //
  1449  // Valid names are "INFO", "WARNING", "ERROR", and "FATAL".  If the name is not
  1450  // recognized, CopyStandardLogTo panics.
  1451  func CopyStandardLogTo(name string) {
  1452  	sev, ok := severityByName(name)
  1453  	if !ok {
  1454  		panic(fmt.Sprintf("log.CopyStandardLogTo(%q): unrecognized severity name", name))
  1455  	}
  1456  	// Set a log format that captures the user's file and line:
  1457  	//   d.go:23: message
  1458  	stdLog.SetFlags(stdLog.Lshortfile)
  1459  	stdLog.SetOutput(logBridge(sev))
  1460  }
  1461  
  1462  // logBridge provides the Write method that enables CopyStandardLogTo to connect
  1463  // Go's standard logs to the logs provided by this package.
  1464  type logBridge severity
  1465  
  1466  // Write parses the standard logging line and passes its components to the
  1467  // logger for severity(lb).
  1468  func (lb logBridge) Write(b []byte) (n int, err error) {
  1469  	var (
  1470  		file = "???"
  1471  		line = 1
  1472  		text string
  1473  	)
  1474  	// Split "d.go:23: message" into "d.go", "23", and "message".
  1475  	if parts := bytes.SplitN(b, []byte{':'}, 3); len(parts) != 3 || len(parts[0]) < 1 || len(parts[2]) < 1 {
  1476  		text = fmt.Sprintf("bad log format: %s", b)
  1477  	} else {
  1478  		file = string(parts[0])
  1479  		text = string(parts[2][1:]) // skip leading space
  1480  		line, err = strconv.Atoi(string(parts[1]))
  1481  		if err != nil {
  1482  			text = fmt.Sprintf("bad line number: %s", b)
  1483  			line = 1
  1484  		}
  1485  	}
  1486  	// printWithFileLine with alsoToStderr=true, so standard log messages
  1487  	// always appear on standard error.
  1488  
  1489  	logging.printWithFileLine(severity(lb), file, line, true, text)
  1490  	return len(b), nil
  1491  }
  1492  
  1493  // setV computes and remembers the V level for a given PC
  1494  // when vmodule is enabled.
  1495  // File pattern matching takes the basename of the file, stripped
  1496  // of its .go suffix, and uses filepath.Match, which is a little more
  1497  // general than the *? matching used in C++.
  1498  // l.mu is held.
  1499  func (l *loggingT) setV(pc uintptr) Level {
  1500  	fn := runtime.FuncForPC(pc)
  1501  	file, _ := fn.FileLine(pc)
  1502  	file = trimToImportPath(file)
  1503  	for _, filter := range l.vmodule.filter {
  1504  		if filter.pattern.MatchString(file) {
  1505  			l.vmap[pc] = filter.level
  1506  			return filter.level
  1507  		}
  1508  	}
  1509  	l.vmap[pc] = 0
  1510  	return 0
  1511  }
  1512  
  1513  // Verbose is a boolean type that implements Infof (like Printf) etc.
  1514  // See the documentation of V for more information.
  1515  type Verbose bool
  1516  type Displayable bool
  1517  
  1518  // V reports whether verbosity at the call site is at least the requested level.
  1519  // The returned value is a boolean of type Verbose, which implements Info, Infoln
  1520  // and Infof. These methods will write to the Info log if called.
  1521  // Thus, one may write either
  1522  //	if glog.V(2) { glog.Info("log this") }
  1523  // or
  1524  //	glog.V(2).Info("log this")
  1525  // The second form is shorter but the first is cheaper if logging is off because it does
  1526  // not evaluate its arguments.
  1527  //
  1528  // Whether an individual call to V generates a log record depends on the setting of
  1529  // the -v and --vmodule flags; both are off by default. If the level in the call to
  1530  // V is at least the value of -v, or of -vmodule for the source file containing the
  1531  // call, the V call will log.
  1532  func V(level Level) Verbose {
  1533  	// This function tries hard to be cheap unless there's work to do.
  1534  	// The fast path is two atomic loads and compares.
  1535  
  1536  	// Here is a cheap but safe test to see if V logging is enabled globally.
  1537  	if logging.verbosity.get() >= level {
  1538  		return Verbose(true)
  1539  	}
  1540  	// It's off globally but it vmodule may still be set.
  1541  	// Here is another cheap but safe test to see if vmodule is enabled.
  1542  	if atomic.LoadInt32(&logging.filterLength) > 0 {
  1543  		// Now we need a proper lock to use the logging structure. The pcs field
  1544  		// is shared so we must lock before accessing it. This is fairly expensive,
  1545  		// but if V logging is enabled we're slow anyway.
  1546  		logging.mu.Lock()
  1547  		defer logging.mu.Unlock()
  1548  		if runtime.Callers(2, logging.pcs[:]) == 0 {
  1549  			return Verbose(false)
  1550  		}
  1551  		v, ok := logging.vmap[logging.pcs[0]]
  1552  		if !ok {
  1553  			v = logging.setV(logging.pcs[0])
  1554  		}
  1555  		return Verbose(v >= level)
  1556  	}
  1557  	return Verbose(false)
  1558  }
  1559  
  1560  func D(level Level) Displayable {
  1561  	// This function tries hard to be cheap unless there's work to do.
  1562  	// The fast path is two atomic loads and compares.
  1563  
  1564  	// Here is a cheap but safe test to see if V logging is enabled globally.
  1565  	if display.verbosity.get() >= level {
  1566  		return Displayable(true)
  1567  	}
  1568  	// It's off globally but it vmodule may still be set.
  1569  	// Here is another cheap but safe test to see if vmodule is enabled.
  1570  	if atomic.LoadInt32(&display.filterLength) > 0 {
  1571  		// Now we need a proper lock to use the logging structure. The pcs field
  1572  		// is shared so we must lock before accessing it. This is fairly expensive,
  1573  		// but if V logging is enabled we're slow anyway.
  1574  		display.mu.Lock()
  1575  		defer display.mu.Unlock()
  1576  		if runtime.Callers(2, display.pcs[:]) == 0 {
  1577  			return Displayable(false)
  1578  		}
  1579  		v, ok := display.vmap[logging.pcs[0]]
  1580  		if !ok {
  1581  			v = display.setV(logging.pcs[0])
  1582  		}
  1583  		return Displayable(v >= level)
  1584  	}
  1585  	return Displayable(false)
  1586  }
  1587  
  1588  func (d Displayable) Infoln(args ...interface{}) {
  1589  	if d {
  1590  		display.println(infoLog, args...)
  1591  	}
  1592  }
  1593  
  1594  func (d Displayable) Infof(format string, args ...interface{}) {
  1595  	if d {
  1596  		display.printfmt(infoLog, format, args...)
  1597  	}
  1598  }
  1599  
  1600  func (d Displayable) Warnln(args ...interface{}) {
  1601  	if d {
  1602  		display.println(warningLog, args...)
  1603  	}
  1604  }
  1605  
  1606  func (d Displayable) Warnf(format string, args ...interface{}) {
  1607  	if d {
  1608  		display.printfmt(warningLog, format, args...)
  1609  	}
  1610  }
  1611  
  1612  func (d Displayable) Errorln(args ...interface{}) {
  1613  	if d {
  1614  		display.println(errorLog, args...)
  1615  	}
  1616  }
  1617  
  1618  func (d Displayable) Errorf(format string, args ...interface{}) {
  1619  	if d {
  1620  		display.printfmt(errorLog, format, args...)
  1621  	}
  1622  }
  1623  
  1624  // INFO
  1625  // Info is equivalent to the global Info function, guarded by the value of v.
  1626  // See the documentation of V for usage.
  1627  func (v Verbose) Info(args ...interface{}) {
  1628  	if v {
  1629  		logging.print(infoLog, args...)
  1630  	}
  1631  }
  1632  
  1633  // Infoln is equivalent to the global Infoln function, guarded by the value of v.
  1634  // See the documentation of V for usage.
  1635  func (v Verbose) Infoln(args ...interface{}) {
  1636  	if v {
  1637  		logging.println(infoLog, args...)
  1638  	}
  1639  }
  1640  
  1641  // Infof is equivalent to the global Infof function, guarded by the value of v.
  1642  // See the documentation of V for usage.
  1643  func (v Verbose) Infof(format string, args ...interface{}) {
  1644  	if v {
  1645  		logging.printfmt(infoLog, format, args...)
  1646  	}
  1647  }
  1648  
  1649  // WARN
  1650  // Warn is equivalent to the global Warn function, guarded by the value of v.
  1651  // See the documentation of V for usage.
  1652  func (v Verbose) Warn(args ...interface{}) {
  1653  	if v {
  1654  		logging.print(warningLog, args...)
  1655  	}
  1656  }
  1657  
  1658  // Warnln is equivalent to the global Warnln function, guarded by the value of v.
  1659  // See the documentation of V for usage.
  1660  func (v Verbose) Warnln(args ...interface{}) {
  1661  	if v {
  1662  		logging.println(warningLog, args...)
  1663  	}
  1664  }
  1665  
  1666  // Warnf is equivalent to the global Warnf function, guarded by the value of v.
  1667  // See the documentation of V for usage.
  1668  func (v Verbose) Warnf(format string, args ...interface{}) {
  1669  	if v {
  1670  		logging.printfmt(warningLog, format, args...)
  1671  	}
  1672  }
  1673  
  1674  // ERROR
  1675  // Error is equivalent to the global Error function, guarded by the value of v.
  1676  // See the documentation of V for usage.
  1677  func (v Verbose) Error(args ...interface{}) {
  1678  	if v {
  1679  		logging.print(errorLog, args...)
  1680  	}
  1681  }
  1682  
  1683  // Errorln is equivalent to the global Errorln function, guarded by the value of v.
  1684  // See the documentation of V for usage.
  1685  func (v Verbose) Errorln(args ...interface{}) {
  1686  	if v {
  1687  		logging.println(errorLog, args...)
  1688  	}
  1689  }
  1690  
  1691  // Errorf is equivalent to the global Errorf function, guarded by the value of v.
  1692  // See the documentation of V for usage.
  1693  func (v Verbose) Errorf(format string, args ...interface{}) {
  1694  	if v {
  1695  		logging.printfmt(errorLog, format, args...)
  1696  	}
  1697  }
  1698  
  1699  // Separator creates a line, ie ---------------------------------
  1700  func Separator(iterable string) string {
  1701  	return strings.Repeat(iterable, 110)
  1702  }
  1703  
  1704  // Info logs to the INFO log.
  1705  // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
  1706  func Info(args ...interface{}) {
  1707  	logging.print(infoLog, args...)
  1708  }
  1709  
  1710  // InfoDepth acts as Info but uses depth to determine which call frame to log.
  1711  // InfoDepth(0, "msg") is the same as Info("msg").
  1712  func InfoDepth(depth int, args ...interface{}) {
  1713  	logging.printDepth(infoLog, depth, args...)
  1714  }
  1715  
  1716  // Infoln logs to the INFO log.
  1717  // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
  1718  func Infoln(args ...interface{}) {
  1719  	logging.print(infoLog, args...)
  1720  }
  1721  
  1722  // Infof logs to the INFO log.
  1723  // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
  1724  func Infof(format string, args ...interface{}) {
  1725  	logging.printfmt(infoLog, format, args...)
  1726  }
  1727  
  1728  // Warning logs to the WARNING and INFO logs.
  1729  // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
  1730  func Warning(args ...interface{}) {
  1731  	logging.print(warningLog, args...)
  1732  }
  1733  
  1734  // WarningDepth acts as Warning but uses depth to determine which call frame to log.
  1735  // WarningDepth(0, "msg") is the same as Warning("msg").
  1736  func WarningDepth(depth int, args ...interface{}) {
  1737  	logging.printDepth(warningLog, depth, args...)
  1738  }
  1739  
  1740  // Warningln logs to the WARNING and INFO logs.
  1741  // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
  1742  func Warningln(args ...interface{}) {
  1743  	logging.println(warningLog, args...)
  1744  }
  1745  
  1746  // Warningf logs to the WARNING and INFO logs.
  1747  // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
  1748  func Warningf(format string, args ...interface{}) {
  1749  	logging.printfmt(warningLog, format, args...)
  1750  }
  1751  
  1752  // Error logs to the ERROR, WARNING, and INFO logs.
  1753  // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
  1754  func Error(args ...interface{}) {
  1755  	logging.print(errorLog, args...)
  1756  }
  1757  
  1758  // ErrorDepth acts as Error but uses depth to determine which call frame to log.
  1759  // ErrorDepth(0, "msg") is the same as Error("msg").
  1760  func ErrorDepth(depth int, args ...interface{}) {
  1761  	logging.printDepth(errorLog, depth, args...)
  1762  }
  1763  
  1764  // Errorln logs to the ERROR, WARNING, and INFO logs.
  1765  // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
  1766  func Errorln(args ...interface{}) {
  1767  	logging.println(errorLog, args...)
  1768  }
  1769  
  1770  // Errorf logs to the ERROR, WARNING, and INFO logs.
  1771  // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
  1772  func Errorf(format string, args ...interface{}) {
  1773  	logging.printfmt(errorLog, format, args...)
  1774  }
  1775  
  1776  // Fatal logs to the FATAL, ERROR, WARNING, and INFO logs,
  1777  // including a stack trace of all running goroutines, then calls os.Exit(255).
  1778  // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
  1779  func Fatal(args ...interface{}) {
  1780  	logging.print(fatalLog, args...)
  1781  }
  1782  
  1783  // FatalDepth acts as Fatal but uses depth to determine which call frame to log.
  1784  // FatalDepth(0, "msg") is the same as Fatal("msg").
  1785  func FatalDepth(depth int, args ...interface{}) {
  1786  	logging.printDepth(fatalLog, depth, args...)
  1787  }
  1788  
  1789  // Fatalln logs to the FATAL, ERROR, WARNING, and INFO logs,
  1790  // including a stack trace of all running goroutines, then calls os.Exit(255).
  1791  // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
  1792  func Fatalln(args ...interface{}) {
  1793  	logging.println(fatalLog, args...)
  1794  }
  1795  
  1796  // Fatalf logs to the FATAL, ERROR, WARNING, and INFO logs,
  1797  // including a stack trace of all running goroutines, then calls os.Exit(255).
  1798  // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
  1799  func Fatalf(format string, args ...interface{}) {
  1800  	logging.printfmt(fatalLog, format, args...)
  1801  }
  1802  
  1803  // fatalNoStacks is non-zero if we are to exit without dumping goroutine stacks.
  1804  // It allows Exit and relatives to use the Fatal logs.
  1805  var fatalNoStacks uint32
  1806  
  1807  // Exit logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
  1808  // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
  1809  func Exit(args ...interface{}) {
  1810  	atomic.StoreUint32(&fatalNoStacks, 1)
  1811  	logging.print(fatalLog, args...)
  1812  }
  1813  
  1814  // ExitDepth acts as Exit but uses depth to determine which call frame to log.
  1815  // ExitDepth(0, "msg") is the same as Exit("msg").
  1816  func ExitDepth(depth int, args ...interface{}) {
  1817  	atomic.StoreUint32(&fatalNoStacks, 1)
  1818  	logging.printDepth(fatalLog, depth, args...)
  1819  }
  1820  
  1821  // Exitln logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
  1822  func Exitln(args ...interface{}) {
  1823  	atomic.StoreUint32(&fatalNoStacks, 1)
  1824  	logging.println(fatalLog, args...)
  1825  }
  1826  
  1827  // Exitf logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
  1828  // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
  1829  func Exitf(format string, args ...interface{}) {
  1830  	atomic.StoreUint32(&fatalNoStacks, 1)
  1831  	logging.printfmt(fatalLog, format, args...)
  1832  }