@@ -414,16 +414,6 @@ func InitFlags(flagset *flag.FlagSet) {
414414 logging .logDir = ""
415415 logging .logFile = ""
416416 logging .logFileMaxSizeMB = 1800
417- // TODO: The default value of toStderr should be false.
418- // Ideally, toStderr can be deprecated.
419- // If --log-file is set, only log to the dedicated log-file.
420- // If --alsoToStderr is true, whether or not --log-file is set, we will
421- // log to stderr.
422- // Since kubernetes/kubernetes are currently using klog with
423- // default --toStderr to be true, we can't change this default value
424- // directly.
425- // As a compromise, when --log-file is set, the toStdErr is reset to
426- // be false. e.g. See function `IsSingleMode`.
427417 logging .toStderr = true
428418 logging .alsoToStderr = false
429419 logging .skipHeaders = false
@@ -477,8 +467,6 @@ type loggingT struct {
477467 mu sync.Mutex
478468 // file holds writer for each of the log types.
479469 file [numSeverity ]flushSyncWriter
480- // file holds writer for the dedicated file when --log-file is set.
481- singleModeFile flushSyncWriter
482470 // pcs is used in V to avoid an allocation when computing the caller's PC.
483471 pcs [1 ]uintptr
484472 // vmap is a cache of the V Level for each V() call site, identified by PC.
@@ -523,16 +511,6 @@ type buffer struct {
523511
524512var logging loggingT
525513
526- func (l * loggingT ) IsSingleMode () bool {
527- if l .logFile != "" {
528- // TODO: Remove the toStdErr reset when switching the logging.toStderr
529- // default value to be false.
530- l .toStderr = false
531- return true
532- }
533- return false
534- }
535-
536514// setVState sets a consistent state for V logging.
537515// l.mu is held.
538516func (l * loggingT ) setVState (verbosity Level , filter []modulePat , setFilter bool ) {
@@ -758,40 +736,24 @@ func (rb *redirectBuffer) Write(bytes []byte) (n int, err error) {
758736
759737// SetOutput sets the output destination for all severities
760738func SetOutput (w io.Writer ) {
761- // In single-mode, all severity logs are tracked in a single dedicated file.
762- if logging .IsSingleMode () {
739+ for s := fatalLog ; s >= infoLog ; s -- {
763740 rb := & redirectBuffer {
764741 w : w ,
765742 }
766- logging .singleModeFile = rb
767- } else {
768- for s := fatalLog ; s >= infoLog ; s -- {
769- rb := & redirectBuffer {
770- w : w ,
771- }
772- logging .file [s ] = rb
773- }
743+ logging .file [s ] = rb
774744 }
775745}
776746
777747// SetOutputBySeverity sets the output destination for specific severity
778748func SetOutputBySeverity (name string , w io.Writer ) {
779- // In single-mode, all severity logs are tracked in a single dedicated file.
780- // Guarantee this buffer exists whatever severity output is trying to be set.
781- if logging .IsSingleMode () {
782- if logging .singleModeFile == nil {
783- logging .singleModeFile = & redirectBuffer {w : w }
784- }
785- } else {
786- sev , ok := severityByName (name )
787- if ! ok {
788- panic (fmt .Sprintf ("SetOutputBySeverity(%q): unrecognized severity name" , name ))
789- }
790- rb := & redirectBuffer {
791- w : w ,
792- }
793- logging .file [sev ] = rb
749+ sev , ok := severityByName (name )
750+ if ! ok {
751+ panic (fmt .Sprintf ("SetOutputBySeverity(%q): unrecognized severity name" , name ))
794752 }
753+ rb := & redirectBuffer {
754+ w : w ,
755+ }
756+ logging .file [sev ] = rb
795757}
796758
797759// output writes the data to the log files and releases the buffer.
@@ -803,73 +765,66 @@ func (l *loggingT) output(s severity, buf *buffer, file string, line int, alsoTo
803765 }
804766 }
805767 data := buf .Bytes ()
806- l .writeLogData (s , data )
768+ if l .toStderr {
769+ os .Stderr .Write (data )
770+ } else {
771+ if alsoToStderr || l .alsoToStderr || s >= l .stderrThreshold .get () {
772+ os .Stderr .Write (data )
773+ }
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.
777+ l .exit (err )
778+ }
779+ }
780+ switch s {
781+ case fatalLog :
782+ l .file [fatalLog ].Write (data )
783+ fallthrough
784+ case errorLog :
785+ l .file [errorLog ].Write (data )
786+ fallthrough
787+ case warningLog :
788+ l .file [warningLog ].Write (data )
789+ fallthrough
790+ case infoLog :
791+ l .file [infoLog ].Write (data )
792+ }
793+ }
807794 if s == fatalLog {
808795 // If we got here via Exit rather than Fatal, print no stacks.
809796 if atomic .LoadUint32 (& fatalNoStacks ) > 0 {
810797 l .mu .Unlock ()
811798 timeoutFlush (10 * time .Second )
812799 os .Exit (1 )
813800 }
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.
805+ if ! l .toStderr {
806+ os .Stderr .Write (stacks (false ))
807+ }
808+ // Write the stack trace for all goroutines to the files.
809+ trace := stacks (true )
814810 logExitFunc = func (error ) {} // If we get a write error, we'll still exit below.
815- l .writeLogData (fatalLog , stacks (true ))
811+ for log := fatalLog ; log >= infoLog ; log -- {
812+ if f := l .file [log ]; f != nil { // Can be nil if -logtostderr is set.
813+ f .Write (trace )
814+ }
815+ }
816816 l .mu .Unlock ()
817817 timeoutFlush (10 * time .Second )
818818 os .Exit (255 ) // C++ uses -1, which is silly because it's anded with 255 anyway.
819819 }
820820 l .putBuffer (buf )
821821 l .mu .Unlock ()
822- // Note: The stats estimate logs for each severity level individually,
823- // even in the situation that log-file is specified and
824- // all severity-level logs are tracked only in the infoLog file.
825822 if stats := severityStats [s ]; stats != nil {
826823 atomic .AddInt64 (& stats .lines , 1 )
827824 atomic .AddInt64 (& stats .bytes , int64 (len (data )))
828825 }
829826}
830827
831- // writeLogData writes |data| to the `s` and lower severity files.
832- // e.g. If Severity level is Error, the data will be written to all the Error,
833- // Warning, and Info log file. However, if --log_file flag is provided, klog
834- // no longer tracks logs separately due to their severity level, but rather
835- // only write to the singleModeFile which later on will be flushed to the
836- // dedicated log_file.
837- func (l * loggingT ) writeLogData (s severity , data []byte ) {
838- shouldAlsoToStderr := l .alsoToStderr && s >= l .stderrThreshold .get ()
839- if l .IsSingleMode () {
840- if shouldAlsoToStderr {
841- os .Stderr .Write (data )
842- }
843- if l .singleModeFile == nil {
844- now := time .Now ()
845- sb := & syncBuffer {
846- logger : l ,
847- maxbytes : CalculateMaxSize (),
848- }
849- if err := sb .rotateFile (now , true ); err != nil {
850- l .exit (err )
851- }
852- l .singleModeFile = sb
853- }
854- l .singleModeFile .Write (data )
855- } else {
856- if l .toStderr || shouldAlsoToStderr {
857- os .Stderr .Write (data )
858- }
859- for currSeverity := s ; currSeverity >= infoLog ; currSeverity -- {
860- if l .file [currSeverity ] == nil {
861- if err := l .createFiles (currSeverity ); err != nil {
862- os .Stderr .Write (data ) // Make sure the message appears somewhere.
863- l .exit (err )
864- }
865- }
866- if f := l .file [currSeverity ]; f != nil { // Can be nil if -logtostderr is set.
867- f .Write (data )
868- }
869- }
870- }
871- }
872-
873828// timeoutFlush calls Flush and returns when it completes or after timeout
874829// elapses, whichever happens first. This is needed because the hooks invoked
875830// by Flush may deadlock when glog.Fatal is called from a hook that holds
@@ -1047,21 +1002,13 @@ func (l *loggingT) lockAndFlushAll() {
10471002// flushAll flushes all the logs and attempts to "sync" their data to disk.
10481003// l.mu is held.
10491004func (l * loggingT ) flushAll () {
1050- if l .IsSingleMode () {
1051- file := l .singleModeFile
1005+ // Flush from fatal down, in case there's trouble flushing.
1006+ for s := fatalLog ; s >= infoLog ; s -- {
1007+ file := l .file [s ]
10521008 if file != nil {
10531009 file .Flush () // ignore error
10541010 file .Sync () // ignore error
10551011 }
1056- } else {
1057- // Flush from fatal down, in case there's trouble flushing.
1058- for s := fatalLog ; s >= infoLog ; s -- {
1059- file := l .file [s ]
1060- if file != nil {
1061- file .Flush () // ignore error
1062- file .Sync () // ignore error
1063- }
1064- }
10651012 }
10661013}
10671014
@@ -1147,9 +1094,9 @@ type Verbose bool
11471094// The returned value is a boolean of type Verbose, which implements Info, Infoln
11481095// and Infof. These methods will write to the Info log if called.
11491096// Thus, one may write either
1150- // if glog.V(2) { glog.Info("log this") }
1097+ // if glog.V(2) { glog.Info("log this") }
11511098// or
1152- // glog.V(2).Info("log this")
1099+ // glog.V(2).Info("log this")
11531100// The second form is shorter but the first is cheaper if logging is off because it does
11541101// not evaluate its arguments.
11551102//
0 commit comments