1 // Go support for leveled logs, analogous to https://code.google.com/p/google-glog/
3 // Copyright 2013 Google Inc. All Rights Reserved.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
17 // Package klog 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.
23 // glog.Info("Prepare to repel boarders")
25 // glog.Fatalf("Initialization failed: %s", err)
27 // See the documentation for the V function for an explanation of these examples:
30 // glog.Info("Starting transaction...")
33 // glog.V(2).Infoln("Processed", nItems, "elements")
35 // Log output is buffered and written periodically using Flush. Programs
36 // should call Flush before exiting to guarantee all log output is written.
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.
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.
50 // Log files will be written to this directory instead of the
51 // default temporary directory.
53 // Other flags provide aids to debugging.
55 // -log_backtrace_at=""
56 // When set to a file and line number holding a logging statement,
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
63 // Enable V-leveled logging at the specified level.
65 // The syntax of the argument is a comma-separated list of pattern=N,
66 // where pattern is a literal file name (minus the ".go" suffix) or
67 // "glob" pattern and N is a V level. For instance,
69 // sets the V level to 3 in all Go files whose names begin "gopher".
92 // severity identifies the sort of log: info, warning etc. It also implements
93 // the flag.Value interface. The -stderrthreshold flag is of type severity and
94 // should be modified only through the flag.Value interface. The values match
95 // the corresponding constants in C++.
96 type severity int32 // sync/atomic int32
98 // These constants identify the log levels in order of increasing severity.
99 // A message written to a high-severity log file is also written to each
100 // lower-severity log file.
102 infoLog severity = iota
109 const severityChar = "IWEF"
111 var severityName = []string{
113 warningLog: "WARNING",
118 // get returns the value of the severity.
119 func (s *severity) get() severity {
120 return severity(atomic.LoadInt32((*int32)(s)))
123 // set sets the value of the severity.
124 func (s *severity) set(val severity) {
125 atomic.StoreInt32((*int32)(s), int32(val))
128 // String is part of the flag.Value interface.
129 func (s *severity) String() string {
130 return strconv.FormatInt(int64(*s), 10)
133 // Get is part of the flag.Value interface.
134 func (s *severity) Get() interface{} {
138 // Set is part of the flag.Value interface.
139 func (s *severity) Set(value string) error {
140 var threshold severity
141 // Is it a known name?
142 if v, ok := severityByName(value); ok {
145 v, err := strconv.Atoi(value)
149 threshold = severity(v)
151 logging.stderrThreshold.set(threshold)
155 func severityByName(s string) (severity, bool) {
156 s = strings.ToUpper(s)
157 for i, name := range severityName {
159 return severity(i), true
165 // OutputStats tracks the number of output lines and bytes written.
166 type OutputStats struct {
171 // Lines returns the number of lines written.
172 func (s *OutputStats) Lines() int64 {
173 return atomic.LoadInt64(&s.lines)
176 // Bytes returns the number of bytes written.
177 func (s *OutputStats) Bytes() int64 {
178 return atomic.LoadInt64(&s.bytes)
181 // Stats tracks the number of lines of output and number of bytes
182 // per severity level. Values must be read with atomic.LoadInt64.
184 Info, Warning, Error OutputStats
187 var severityStats = [numSeverity]*OutputStats{
188 infoLog: &Stats.Info,
189 warningLog: &Stats.Warning,
190 errorLog: &Stats.Error,
193 // Level is exported because it appears in the arguments to V and is
194 // the type of the v flag, which can be set programmatically.
195 // It's a distinct type because we want to discriminate it from logType.
196 // Variables of type level are only changed under logging.mu.
197 // The -v flag is read only with atomic ops, so the state of the logging
198 // module is consistent.
200 // Level is treated as a sync/atomic int32.
202 // Level specifies a level of verbosity for V logs. *Level implements
203 // flag.Value; the -v flag is of type Level and should be modified
204 // only through the flag.Value interface.
207 // get returns the value of the Level.
208 func (l *Level) get() Level {
209 return Level(atomic.LoadInt32((*int32)(l)))
212 // set sets the value of the Level.
213 func (l *Level) set(val Level) {
214 atomic.StoreInt32((*int32)(l), int32(val))
217 // String is part of the flag.Value interface.
218 func (l *Level) String() string {
219 return strconv.FormatInt(int64(*l), 10)
222 // Get is part of the flag.Value interface.
223 func (l *Level) Get() interface{} {
227 // Set is part of the flag.Value interface.
228 func (l *Level) Set(value string) error {
229 v, err := strconv.Atoi(value)
234 defer logging.mu.Unlock()
235 logging.setVState(Level(v), logging.vmodule.filter, false)
239 // moduleSpec represents the setting of the -vmodule flag.
240 type moduleSpec struct {
244 // modulePat contains a filter for the -vmodule flag.
245 // It holds a verbosity level and a file pattern to match.
246 type modulePat struct {
248 literal bool // The pattern is a literal string
252 // match reports whether the file matches the pattern. It uses a string
253 // comparison if the pattern contains no metacharacters.
254 func (m *modulePat) match(file string) bool {
256 return file == m.pattern
258 match, _ := filepath.Match(m.pattern, file)
262 func (m *moduleSpec) String() string {
263 // Lock because the type is not atomic. TODO: clean this up.
265 defer logging.mu.Unlock()
267 for i, f := range m.filter {
271 fmt.Fprintf(&b, "%s=%d", f.pattern, f.level)
276 // Get is part of the (Go 1.2) flag.Getter interface. It always returns nil for this flag type since the
277 // struct is not exported.
278 func (m *moduleSpec) Get() interface{} {
282 var errVmoduleSyntax = errors.New("syntax error: expect comma-separated list of filename=N")
284 // Syntax: -vmodule=recordio=2,file=1,gfs*=3
285 func (m *moduleSpec) Set(value string) error {
286 var filter []modulePat
287 for _, pat := range strings.Split(value, ",") {
289 // Empty strings such as from a trailing comma can be ignored.
292 patLev := strings.Split(pat, "=")
293 if len(patLev) != 2 || len(patLev[0]) == 0 || len(patLev[1]) == 0 {
294 return errVmoduleSyntax
297 v, err := strconv.Atoi(patLev[1])
299 return errors.New("syntax error: expect comma-separated list of filename=N")
302 return errors.New("negative value for vmodule level")
305 continue // Ignore. It's harmless but no point in paying the overhead.
307 // TODO: check syntax of filter?
308 filter = append(filter, modulePat{pattern, isLiteral(pattern), Level(v)})
311 defer logging.mu.Unlock()
312 logging.setVState(logging.verbosity, filter, true)
316 // isLiteral reports whether the pattern is a literal string, that is, has no metacharacters
317 // that require filepath.Match to be called to match the pattern.
318 func isLiteral(pattern string) bool {
319 return !strings.ContainsAny(pattern, `\*?[]`)
322 // traceLocation represents the setting of the -log_backtrace_at flag.
323 type traceLocation struct {
328 // isSet reports whether the trace location has been specified.
329 // logging.mu is held.
330 func (t *traceLocation) isSet() bool {
334 // match reports whether the specified file and line matches the trace location.
335 // The argument file name is the full path, not the basename specified in the flag.
336 // logging.mu is held.
337 func (t *traceLocation) match(file string, line int) bool {
341 if i := strings.LastIndex(file, "/"); i >= 0 {
344 return t.file == file
347 func (t *traceLocation) String() string {
348 // Lock because the type is not atomic. TODO: clean this up.
350 defer logging.mu.Unlock()
351 return fmt.Sprintf("%s:%d", t.file, t.line)
354 // Get is part of the (Go 1.2) flag.Getter interface. It always returns nil for this flag type since the
355 // struct is not exported
356 func (t *traceLocation) Get() interface{} {
360 var errTraceSyntax = errors.New("syntax error: expect file.go:234")
362 // Syntax: -log_backtrace_at=gopherflakes.go:234
363 // Note that unlike vmodule the file extension is included here.
364 func (t *traceLocation) Set(value string) error {
370 fields := strings.Split(value, ":")
371 if len(fields) != 2 {
372 return errTraceSyntax
374 file, line := fields[0], fields[1]
375 if !strings.Contains(file, ".") {
376 return errTraceSyntax
378 v, err := strconv.Atoi(line)
380 return errTraceSyntax
383 return errors.New("negative or zero value for level")
386 defer logging.mu.Unlock()
392 // flushSyncWriter is the interface satisfied by logging destinations.
393 type flushSyncWriter interface {
400 // Default stderrThreshold is ERROR.
401 logging.stderrThreshold = errorLog
403 logging.setVState(0, nil, false)
404 go logging.flushDaemon()
407 var initDefaultsOnce sync.Once
409 // InitFlags is for explicitly initializing the flags.
410 func InitFlags(flagset *flag.FlagSet) {
412 // Initialize defaults.
413 initDefaultsOnce.Do(func() {
416 logging.logFileMaxSizeMB = 1800
417 logging.toStderr = true
418 logging.alsoToStderr = false
419 logging.skipHeaders = false
420 logging.skipLogHeaders = false
424 flagset = flag.CommandLine
427 flagset.StringVar(&logging.logDir, "log_dir", logging.logDir, "If non-empty, write log files in this directory")
428 flagset.StringVar(&logging.logFile, "log_file", logging.logFile, "If non-empty, use this log file")
429 flagset.Uint64Var(&logging.logFileMaxSizeMB, "log_file_max_size", logging.logFileMaxSizeMB,
430 "Defines the maximum size a log file can grow to. Unit is megabytes. "+
431 "If the value is 0, the maximum file size is unlimited.")
432 flagset.BoolVar(&logging.toStderr, "logtostderr", logging.toStderr, "log to standard error instead of files")
433 flagset.BoolVar(&logging.alsoToStderr, "alsologtostderr", logging.alsoToStderr, "log to standard error as well as files")
434 flagset.Var(&logging.verbosity, "v", "number for the log level verbosity")
435 flagset.BoolVar(&logging.skipHeaders, "skip_headers", logging.skipHeaders, "If true, avoid header prefixes in the log messages")
436 flagset.BoolVar(&logging.skipLogHeaders, "skip_log_headers", logging.skipLogHeaders, "If true, avoid headers when opening log files")
437 flagset.Var(&logging.stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr")
438 flagset.Var(&logging.vmodule, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging")
439 flagset.Var(&logging.traceLocation, "log_backtrace_at", "when logging hits line file:N, emit a stack trace")
442 // Flush flushes all pending log I/O.
444 logging.lockAndFlushAll()
447 // loggingT collects all the global state of the logging setup.
448 type loggingT struct {
449 // Boolean flags. Not handled atomically because the flag.Value interface
450 // does not let us avoid the =true, and that shorthand is necessary for
451 // compatibility. TODO: does this matter enough to fix? Seems unlikely.
452 toStderr bool // The -logtostderr flag.
453 alsoToStderr bool // The -alsologtostderr flag.
455 // Level flag. Handled atomically.
456 stderrThreshold severity // The -stderrthreshold flag.
458 // freeList is a list of byte buffers, maintained under freeListMu.
460 // freeListMu maintains the free list. It is separate from the main mutex
461 // so buffers can be grabbed and printed to without holding the main lock,
462 // for better parallelization.
463 freeListMu sync.Mutex
465 // mu protects the remaining elements of this structure and is
466 // used to synchronize logging.
468 // file holds writer for each of the log types.
469 file [numSeverity]flushSyncWriter
470 // pcs is used in V to avoid an allocation when computing the caller's PC.
472 // vmap is a cache of the V Level for each V() call site, identified by PC.
473 // It is wiped whenever the vmodule flag changes state.
474 vmap map[uintptr]Level
475 // filterLength stores the length of the vmodule filter chain. If greater
476 // than zero, it means vmodule is enabled. It may be read safely
477 // using sync.LoadInt32, but is only modified under mu.
479 // traceLocation is the state of the -log_backtrace_at flag.
480 traceLocation traceLocation
481 // These flags are modified only under lock, although verbosity may be fetched
482 // safely using atomic.LoadInt32.
483 vmodule moduleSpec // The state of the -vmodule flag.
484 verbosity Level // V logging level, the value of the -v flag/
486 // If non-empty, overrides the choice of directory in which to write logs.
487 // See createLogDirs for the full list of possible destinations.
490 // If non-empty, specifies the path of the file to write logs. mutually exclusive
491 // with the log-dir option.
494 // When logFile is specified, this limiter makes sure the logFile won't exceeds a certain size. When exceeds, the
495 // logFile will be cleaned up. If this value is 0, no size limitation will be applied to logFile.
496 logFileMaxSizeMB uint64
498 // If true, do not add the prefix headers, useful when used with SetOutput
501 // If true, do not add the headers to log files
505 // buffer holds a byte Buffer for reuse. The zero value is ready for use.
508 tmp [64]byte // temporary byte array for creating headers.
514 // setVState sets a consistent state for V logging.
516 func (l *loggingT) setVState(verbosity Level, filter []modulePat, setFilter bool) {
517 // Turn verbosity off so V will not fire while we are in transition.
518 logging.verbosity.set(0)
519 // Ditto for filter length.
520 atomic.StoreInt32(&logging.filterLength, 0)
522 // Set the new filters and wipe the pc->Level map if the filter has changed.
524 logging.vmodule.filter = filter
525 logging.vmap = make(map[uintptr]Level)
528 // Things are consistent now, so enable filtering and verbosity.
529 // They are enabled in order opposite to that in V.
530 atomic.StoreInt32(&logging.filterLength, int32(len(filter)))
531 logging.verbosity.set(verbosity)
534 // getBuffer returns a new, ready-to-use buffer.
535 func (l *loggingT) getBuffer() *buffer {
541 l.freeListMu.Unlock()
551 // putBuffer returns a buffer to the free list.
552 func (l *loggingT) putBuffer(b *buffer) {
554 // Let big buffers die a natural death.
560 l.freeListMu.Unlock()
563 var timeNow = time.Now // Stubbed out for testing.
566 header formats a log header as defined by the C++ implementation.
567 It returns a buffer containing the formatted header and the user's file and line number.
568 The depth specifies how many stack frames above lives the source line to be identified in the log message.
570 Log lines have this form:
571 Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg...
572 where the fields are defined as follows:
573 L A single character, representing the log level (eg 'I' for INFO)
574 mm The month (zero padded; ie May is '05')
575 dd The day (zero padded)
576 hh:mm:ss.uuuuuu Time in hours, minutes and fractional seconds
577 threadid The space-padded thread ID as returned by GetTID()
580 msg The user-supplied message
582 func (l *loggingT) header(s severity, depth int) (*buffer, string, int) {
583 _, file, line, ok := runtime.Caller(3 + depth)
588 slash := strings.LastIndex(file, "/")
590 file = file[slash+1:]
593 return l.formatHeader(s, file, line), file, line
596 // formatHeader formats a log header using the provided file name and line number.
597 func (l *loggingT) formatHeader(s severity, file string, line int) *buffer {
600 line = 0 // not a real line number, but acceptable to someDigits
603 s = infoLog // for safety.
610 // Avoid Fprintf, for speed. The format is so simple that we can do it quickly by hand.
611 // It's worth about 3X. Fprintf is hard.
612 _, month, day := now.Date()
613 hour, minute, second := now.Clock()
614 // Lmmdd hh:mm:ss.uuuuuu threadid file:line]
615 buf.tmp[0] = severityChar[s]
616 buf.twoDigits(1, int(month))
617 buf.twoDigits(3, day)
619 buf.twoDigits(6, hour)
621 buf.twoDigits(9, minute)
623 buf.twoDigits(12, second)
625 buf.nDigits(6, 15, now.Nanosecond()/1000, '0')
627 buf.nDigits(7, 22, pid, ' ') // TODO: should be TID
629 buf.Write(buf.tmp[:30])
630 buf.WriteString(file)
632 n := buf.someDigits(1, line)
635 buf.Write(buf.tmp[:n+3])
639 // Some custom tiny helper functions to print the log header efficiently.
641 const digits = "0123456789"
643 // twoDigits formats a zero-prefixed two-digit integer at buf.tmp[i].
644 func (buf *buffer) twoDigits(i, d int) {
645 buf.tmp[i+1] = digits[d%10]
647 buf.tmp[i] = digits[d%10]
650 // nDigits formats an n-digit integer at buf.tmp[i],
651 // padding with pad on the left.
652 // It assumes d >= 0.
653 func (buf *buffer) nDigits(n, i, d int, pad byte) {
655 for ; j >= 0 && d > 0; j-- {
656 buf.tmp[i+j] = digits[d%10]
664 // someDigits formats a zero-prefixed variable-width integer at buf.tmp[i].
665 func (buf *buffer) someDigits(i, d int) int {
666 // Print into the top, then copy down. We know there's space for at least
667 // a 10-digit number.
671 buf.tmp[j] = digits[d%10]
677 return copy(buf.tmp[i:], buf.tmp[j:])
680 func (l *loggingT) println(s severity, args ...interface{}) {
681 buf, file, line := l.header(s, 0)
682 fmt.Fprintln(buf, args...)
683 l.output(s, buf, file, line, false)
686 func (l *loggingT) print(s severity, args ...interface{}) {
687 l.printDepth(s, 1, args...)
690 func (l *loggingT) printDepth(s severity, depth int, args ...interface{}) {
691 buf, file, line := l.header(s, depth)
692 fmt.Fprint(buf, args...)
693 if buf.Bytes()[buf.Len()-1] != '\n' {
696 l.output(s, buf, file, line, false)
699 func (l *loggingT) printf(s severity, format string, args ...interface{}) {
700 buf, file, line := l.header(s, 0)
701 fmt.Fprintf(buf, format, args...)
702 if buf.Bytes()[buf.Len()-1] != '\n' {
705 l.output(s, buf, file, line, false)
708 // printWithFileLine behaves like print but uses the provided file and line number. If
709 // alsoLogToStderr is true, the log message always appears on standard error; it
710 // will also appear in the log file unless --logtostderr is set.
711 func (l *loggingT) printWithFileLine(s severity, file string, line int, alsoToStderr bool, args ...interface{}) {
712 buf := l.formatHeader(s, file, line)
713 fmt.Fprint(buf, args...)
714 if buf.Bytes()[buf.Len()-1] != '\n' {
717 l.output(s, buf, file, line, alsoToStderr)
720 // redirectBuffer is used to set an alternate destination for the logs
721 type redirectBuffer struct {
725 func (rb *redirectBuffer) Sync() error {
729 func (rb *redirectBuffer) Flush() error {
733 func (rb *redirectBuffer) Write(bytes []byte) (n int, err error) {
734 return rb.w.Write(bytes)
737 // SetOutput sets the output destination for all severities
738 func SetOutput(w io.Writer) {
739 for s := fatalLog; s >= infoLog; s-- {
740 rb := &redirectBuffer{
747 // SetOutputBySeverity sets the output destination for specific severity
748 func SetOutputBySeverity(name string, w io.Writer) {
749 sev, ok := severityByName(name)
751 panic(fmt.Sprintf("SetOutputBySeverity(%q): unrecognized severity name", name))
753 rb := &redirectBuffer{
756 logging.file[sev] = rb
759 // output writes the data to the log files and releases the buffer.
760 func (l *loggingT) output(s severity, buf *buffer, file string, line int, alsoToStderr bool) {
762 if l.traceLocation.isSet() {
763 if l.traceLocation.match(file, line) {
764 buf.Write(stacks(false))
769 os.Stderr.Write(data)
771 if alsoToStderr || l.alsoToStderr || s >= l.stderrThreshold.get() {
772 os.Stderr.Write(data)
774 if l.file[s] == nil {
775 if err := l.createFiles(s); err != nil {
776 os.Stderr.Write(data) // Make sure the message appears somewhere.
782 l.file[fatalLog].Write(data)
785 l.file[errorLog].Write(data)
788 l.file[warningLog].Write(data)
791 l.file[infoLog].Write(data)
795 // If we got here via Exit rather than Fatal, print no stacks.
796 if atomic.LoadUint32(&fatalNoStacks) > 0 {
798 timeoutFlush(10 * time.Second)
801 // Dump all goroutine stacks before exiting.
802 // First, make sure we see the trace for the current goroutine on standard error.
803 // If -logtostderr has been specified, the loop below will do that anyway
804 // as the first stack in the full dump.
806 os.Stderr.Write(stacks(false))
808 // Write the stack trace for all goroutines to the files.
809 trace := stacks(true)
810 logExitFunc = func(error) {} // If we get a write error, we'll still exit below.
811 for log := fatalLog; log >= infoLog; log-- {
812 if f := l.file[log]; f != nil { // Can be nil if -logtostderr is set.
817 timeoutFlush(10 * time.Second)
818 os.Exit(255) // C++ uses -1, which is silly because it's anded with 255 anyway.
822 if stats := severityStats[s]; stats != nil {
823 atomic.AddInt64(&stats.lines, 1)
824 atomic.AddInt64(&stats.bytes, int64(len(data)))
828 // timeoutFlush calls Flush and returns when it completes or after timeout
829 // elapses, whichever happens first. This is needed because the hooks invoked
830 // by Flush may deadlock when glog.Fatal is called from a hook that holds
832 func timeoutFlush(timeout time.Duration) {
833 done := make(chan bool, 1)
835 Flush() // calls logging.lockAndFlushAll()
840 case <-time.After(timeout):
841 fmt.Fprintln(os.Stderr, "glog: Flush took longer than", timeout)
845 // stacks is a wrapper for runtime.Stack that attempts to recover the data for all goroutines.
846 func stacks(all bool) []byte {
847 // We don't know how big the traces are, so grow a few times if they don't fit. Start large, though.
853 for i := 0; i < 5; i++ {
854 trace = make([]byte, n)
855 nbytes := runtime.Stack(trace, all)
856 if nbytes < len(trace) {
857 return trace[:nbytes]
864 // logExitFunc provides a simple mechanism to override the default behavior
865 // of exiting on error. Used in testing and to guarantee we reach a required exit
866 // for fatal logs. Instead, exit could be a function rather than a method but that
867 // would make its use clumsier.
868 var logExitFunc func(error)
870 // exit is called if there is trouble creating or writing log files.
871 // It flushes the logs and exits the program; there's no point in hanging around.
873 func (l *loggingT) exit(err error) {
874 fmt.Fprintf(os.Stderr, "log: exiting because of error: %s\n", err)
875 // If logExitFunc is set, we do that instead of exiting.
876 if logExitFunc != nil {
884 // syncBuffer joins a bufio.Writer to its underlying file, providing access to the
885 // file's Sync method and providing a wrapper for the Write method that provides log
886 // file rotation. There are conflicting methods, so the file cannot be embedded.
887 // l.mu is held for all its methods.
888 type syncBuffer struct {
893 nbytes uint64 // The number of bytes written to this file
894 maxbytes uint64 // The max number of bytes this syncBuffer.file can hold before cleaning up.
897 func (sb *syncBuffer) Sync() error {
898 return sb.file.Sync()
901 // CalculateMaxSize returns the real max size in bytes after considering the default max size and the flag options.
902 func CalculateMaxSize() uint64 {
903 if logging.logFile != "" {
904 if logging.logFileMaxSizeMB == 0 {
905 // If logFileMaxSizeMB is zero, we don't have limitations on the log size.
906 return math.MaxUint64
908 // Flag logFileMaxSizeMB is in MB for user convenience.
909 return logging.logFileMaxSizeMB * 1024 * 1024
911 // If "log_file" flag is not specified, the target file (sb.file) will be cleaned up when reaches a fixed size.
915 func (sb *syncBuffer) Write(p []byte) (n int, err error) {
916 if sb.nbytes+uint64(len(p)) >= sb.maxbytes {
917 if err := sb.rotateFile(time.Now(), false); err != nil {
921 n, err = sb.Writer.Write(p)
922 sb.nbytes += uint64(n)
929 // rotateFile closes the syncBuffer's file and starts a new one.
930 // The startup argument indicates whether this is the initial startup of klog.
931 // If startup is true, existing files are opened for appending instead of truncated.
932 func (sb *syncBuffer) rotateFile(now time.Time, startup bool) error {
938 sb.file, _, err = create(severityName[sb.sev], now, startup)
944 sb.Writer = bufio.NewWriterSize(sb.file, bufferSize)
946 if sb.logger.skipLogHeaders {
952 fmt.Fprintf(&buf, "Log file created at: %s\n", now.Format("2006/01/02 15:04:05"))
953 fmt.Fprintf(&buf, "Running on machine: %s\n", host)
954 fmt.Fprintf(&buf, "Binary: Built with %s %s for %s/%s\n", runtime.Compiler, runtime.Version(), runtime.GOOS, runtime.GOARCH)
955 fmt.Fprintf(&buf, "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg\n")
956 n, err := sb.file.Write(buf.Bytes())
957 sb.nbytes += uint64(n)
961 // bufferSize sizes the buffer associated with each log file. It's large
962 // so that log records can accumulate without the logging thread blocking
963 // on disk I/O. The flushDaemon will block instead.
964 const bufferSize = 256 * 1024
966 // createFiles creates all the log files for severity from sev down to infoLog.
968 func (l *loggingT) createFiles(sev severity) error {
970 // Files are created in decreasing severity order, so as soon as we find one
971 // has already been created, we can stop.
972 for s := sev; s >= infoLog && l.file[s] == nil; s-- {
976 maxbytes: CalculateMaxSize(),
978 if err := sb.rotateFile(now, true); err != nil {
986 const flushInterval = 5 * time.Second
988 // flushDaemon periodically flushes the log file buffers.
989 func (l *loggingT) flushDaemon() {
990 for range time.NewTicker(flushInterval).C {
995 // lockAndFlushAll is like flushAll but locks l.mu first.
996 func (l *loggingT) lockAndFlushAll() {
1002 // flushAll flushes all the logs and attempts to "sync" their data to disk.
1004 func (l *loggingT) flushAll() {
1005 // Flush from fatal down, in case there's trouble flushing.
1006 for s := fatalLog; s >= infoLog; s-- {
1009 file.Flush() // ignore error
1010 file.Sync() // ignore error
1015 // CopyStandardLogTo arranges for messages written to the Go "log" package's
1016 // default logs to also appear in the Google logs for the named and lower
1017 // severities. Subsequent changes to the standard log's default output location
1018 // or format may break this behavior.
1020 // Valid names are "INFO", "WARNING", "ERROR", and "FATAL". If the name is not
1021 // recognized, CopyStandardLogTo panics.
1022 func CopyStandardLogTo(name string) {
1023 sev, ok := severityByName(name)
1025 panic(fmt.Sprintf("log.CopyStandardLogTo(%q): unrecognized severity name", name))
1027 // Set a log format that captures the user's file and line:
1029 stdLog.SetFlags(stdLog.Lshortfile)
1030 stdLog.SetOutput(logBridge(sev))
1033 // logBridge provides the Write method that enables CopyStandardLogTo to connect
1034 // Go's standard logs to the logs provided by this package.
1035 type logBridge severity
1037 // Write parses the standard logging line and passes its components to the
1038 // logger for severity(lb).
1039 func (lb logBridge) Write(b []byte) (n int, err error) {
1045 // Split "d.go:23: message" into "d.go", "23", and "message".
1046 if parts := bytes.SplitN(b, []byte{':'}, 3); len(parts) != 3 || len(parts[0]) < 1 || len(parts[2]) < 1 {
1047 text = fmt.Sprintf("bad log format: %s", b)
1049 file = string(parts[0])
1050 text = string(parts[2][1:]) // skip leading space
1051 line, err = strconv.Atoi(string(parts[1]))
1053 text = fmt.Sprintf("bad line number: %s", b)
1057 // printWithFileLine with alsoToStderr=true, so standard log messages
1058 // always appear on standard error.
1059 logging.printWithFileLine(severity(lb), file, line, true, text)
1063 // setV computes and remembers the V level for a given PC
1064 // when vmodule is enabled.
1065 // File pattern matching takes the basename of the file, stripped
1066 // of its .go suffix, and uses filepath.Match, which is a little more
1067 // general than the *? matching used in C++.
1069 func (l *loggingT) setV(pc uintptr) Level {
1070 fn := runtime.FuncForPC(pc)
1071 file, _ := fn.FileLine(pc)
1072 // The file is something like /a/b/c/d.go. We want just the d.
1073 if strings.HasSuffix(file, ".go") {
1074 file = file[:len(file)-3]
1076 if slash := strings.LastIndex(file, "/"); slash >= 0 {
1077 file = file[slash+1:]
1079 for _, filter := range l.vmodule.filter {
1080 if filter.match(file) {
1081 l.vmap[pc] = filter.level
1089 // Verbose is a boolean type that implements Infof (like Printf) etc.
1090 // See the documentation of V for more information.
1093 // V reports whether verbosity at the call site is at least the requested level.
1094 // The returned value is a boolean of type Verbose, which implements Info, Infoln
1095 // and Infof. These methods will write to the Info log if called.
1096 // Thus, one may write either
1097 // if glog.V(2) { glog.Info("log this") }
1099 // glog.V(2).Info("log this")
1100 // The second form is shorter but the first is cheaper if logging is off because it does
1101 // not evaluate its arguments.
1103 // Whether an individual call to V generates a log record depends on the setting of
1104 // the -v and --vmodule flags; both are off by default. If the level in the call to
1105 // V is at least the value of -v, or of -vmodule for the source file containing the
1106 // call, the V call will log.
1107 func V(level Level) Verbose {
1108 // This function tries hard to be cheap unless there's work to do.
1109 // The fast path is two atomic loads and compares.
1111 // Here is a cheap but safe test to see if V logging is enabled globally.
1112 if logging.verbosity.get() >= level {
1113 return Verbose(true)
1116 // It's off globally but it vmodule may still be set.
1117 // Here is another cheap but safe test to see if vmodule is enabled.
1118 if atomic.LoadInt32(&logging.filterLength) > 0 {
1119 // Now we need a proper lock to use the logging structure. The pcs field
1120 // is shared so we must lock before accessing it. This is fairly expensive,
1121 // but if V logging is enabled we're slow anyway.
1123 defer logging.mu.Unlock()
1124 if runtime.Callers(2, logging.pcs[:]) == 0 {
1125 return Verbose(false)
1127 v, ok := logging.vmap[logging.pcs[0]]
1129 v = logging.setV(logging.pcs[0])
1131 return Verbose(v >= level)
1133 return Verbose(false)
1136 // Info is equivalent to the global Info function, guarded by the value of v.
1137 // See the documentation of V for usage.
1138 func (v Verbose) Info(args ...interface{}) {
1140 logging.print(infoLog, args...)
1144 // Infoln is equivalent to the global Infoln function, guarded by the value of v.
1145 // See the documentation of V for usage.
1146 func (v Verbose) Infoln(args ...interface{}) {
1148 logging.println(infoLog, args...)
1152 // Infof is equivalent to the global Infof function, guarded by the value of v.
1153 // See the documentation of V for usage.
1154 func (v Verbose) Infof(format string, args ...interface{}) {
1156 logging.printf(infoLog, format, args...)
1160 // Info logs to the INFO log.
1161 // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
1162 func Info(args ...interface{}) {
1163 logging.print(infoLog, args...)
1166 // InfoDepth acts as Info but uses depth to determine which call frame to log.
1167 // InfoDepth(0, "msg") is the same as Info("msg").
1168 func InfoDepth(depth int, args ...interface{}) {
1169 logging.printDepth(infoLog, depth, args...)
1172 // Infoln logs to the INFO log.
1173 // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
1174 func Infoln(args ...interface{}) {
1175 logging.println(infoLog, args...)
1178 // Infof logs to the INFO log.
1179 // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
1180 func Infof(format string, args ...interface{}) {
1181 logging.printf(infoLog, format, args...)
1184 // Warning logs to the WARNING and INFO logs.
1185 // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
1186 func Warning(args ...interface{}) {
1187 logging.print(warningLog, args...)
1190 // WarningDepth acts as Warning but uses depth to determine which call frame to log.
1191 // WarningDepth(0, "msg") is the same as Warning("msg").
1192 func WarningDepth(depth int, args ...interface{}) {
1193 logging.printDepth(warningLog, depth, args...)
1196 // Warningln logs to the WARNING and INFO logs.
1197 // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
1198 func Warningln(args ...interface{}) {
1199 logging.println(warningLog, args...)
1202 // Warningf logs to the WARNING and INFO logs.
1203 // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
1204 func Warningf(format string, args ...interface{}) {
1205 logging.printf(warningLog, format, args...)
1208 // Error logs to the ERROR, WARNING, and INFO logs.
1209 // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
1210 func Error(args ...interface{}) {
1211 logging.print(errorLog, args...)
1214 // ErrorDepth acts as Error but uses depth to determine which call frame to log.
1215 // ErrorDepth(0, "msg") is the same as Error("msg").
1216 func ErrorDepth(depth int, args ...interface{}) {
1217 logging.printDepth(errorLog, depth, args...)
1220 // Errorln logs to the ERROR, WARNING, and INFO logs.
1221 // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
1222 func Errorln(args ...interface{}) {
1223 logging.println(errorLog, args...)
1226 // Errorf logs to the ERROR, WARNING, and INFO logs.
1227 // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
1228 func Errorf(format string, args ...interface{}) {
1229 logging.printf(errorLog, format, args...)
1232 // Fatal logs to the FATAL, ERROR, WARNING, and INFO logs,
1233 // including a stack trace of all running goroutines, then calls os.Exit(255).
1234 // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
1235 func Fatal(args ...interface{}) {
1236 logging.print(fatalLog, args...)
1239 // FatalDepth acts as Fatal but uses depth to determine which call frame to log.
1240 // FatalDepth(0, "msg") is the same as Fatal("msg").
1241 func FatalDepth(depth int, args ...interface{}) {
1242 logging.printDepth(fatalLog, depth, args...)
1245 // Fatalln logs to the FATAL, ERROR, WARNING, and INFO logs,
1246 // including a stack trace of all running goroutines, then calls os.Exit(255).
1247 // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
1248 func Fatalln(args ...interface{}) {
1249 logging.println(fatalLog, args...)
1252 // Fatalf logs to the FATAL, ERROR, WARNING, and INFO logs,
1253 // including a stack trace of all running goroutines, then calls os.Exit(255).
1254 // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
1255 func Fatalf(format string, args ...interface{}) {
1256 logging.printf(fatalLog, format, args...)
1259 // fatalNoStacks is non-zero if we are to exit without dumping goroutine stacks.
1260 // It allows Exit and relatives to use the Fatal logs.
1261 var fatalNoStacks uint32
1263 // Exit logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
1264 // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
1265 func Exit(args ...interface{}) {
1266 atomic.StoreUint32(&fatalNoStacks, 1)
1267 logging.print(fatalLog, args...)
1270 // ExitDepth acts as Exit but uses depth to determine which call frame to log.
1271 // ExitDepth(0, "msg") is the same as Exit("msg").
1272 func ExitDepth(depth int, args ...interface{}) {
1273 atomic.StoreUint32(&fatalNoStacks, 1)
1274 logging.printDepth(fatalLog, depth, args...)
1277 // Exitln logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
1278 func Exitln(args ...interface{}) {
1279 atomic.StoreUint32(&fatalNoStacks, 1)
1280 logging.println(fatalLog, args...)
1283 // Exitf logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
1284 // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
1285 func Exitf(format string, args ...interface{}) {
1286 atomic.StoreUint32(&fatalNoStacks, 1)
1287 logging.printf(fatalLog, format, args...)