@@ -414,16 +414,6 @@ func InitFlags(flagset *flag.FlagSet) {
414
414
logging .logDir = ""
415
415
logging .logFile = ""
416
416
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`.
427
417
logging .toStderr = true
428
418
logging .alsoToStderr = false
429
419
logging .skipHeaders = false
@@ -477,8 +467,6 @@ type loggingT struct {
477
467
mu sync.Mutex
478
468
// file holds writer for each of the log types.
479
469
file [numSeverity ]flushSyncWriter
480
- // file holds writer for the dedicated file when --log-file is set.
481
- singleModeFile flushSyncWriter
482
470
// pcs is used in V to avoid an allocation when computing the caller's PC.
483
471
pcs [1 ]uintptr
484
472
// vmap is a cache of the V Level for each V() call site, identified by PC.
@@ -523,16 +511,6 @@ type buffer struct {
523
511
524
512
var logging loggingT
525
513
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
-
536
514
// setVState sets a consistent state for V logging.
537
515
// l.mu is held.
538
516
func (l * loggingT ) setVState (verbosity Level , filter []modulePat , setFilter bool ) {
@@ -758,40 +736,24 @@ func (rb *redirectBuffer) Write(bytes []byte) (n int, err error) {
758
736
759
737
// SetOutput sets the output destination for all severities
760
738
func 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 -- {
763
740
rb := & redirectBuffer {
764
741
w : w ,
765
742
}
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
774
744
}
775
745
}
776
746
777
747
// SetOutputBySeverity sets the output destination for specific severity
778
748
func 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 ))
794
752
}
753
+ rb := & redirectBuffer {
754
+ w : w ,
755
+ }
756
+ logging .file [sev ] = rb
795
757
}
796
758
797
759
// 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
803
765
}
804
766
}
805
767
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
+ }
807
794
if s == fatalLog {
808
795
// If we got here via Exit rather than Fatal, print no stacks.
809
796
if atomic .LoadUint32 (& fatalNoStacks ) > 0 {
810
797
l .mu .Unlock ()
811
798
timeoutFlush (10 * time .Second )
812
799
os .Exit (1 )
813
800
}
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 )
814
810
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
+ }
816
816
l .mu .Unlock ()
817
817
timeoutFlush (10 * time .Second )
818
818
os .Exit (255 ) // C++ uses -1, which is silly because it's anded with 255 anyway.
819
819
}
820
820
l .putBuffer (buf )
821
821
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.
825
822
if stats := severityStats [s ]; stats != nil {
826
823
atomic .AddInt64 (& stats .lines , 1 )
827
824
atomic .AddInt64 (& stats .bytes , int64 (len (data )))
828
825
}
829
826
}
830
827
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
-
873
828
// timeoutFlush calls Flush and returns when it completes or after timeout
874
829
// elapses, whichever happens first. This is needed because the hooks invoked
875
830
// by Flush may deadlock when glog.Fatal is called from a hook that holds
@@ -1047,21 +1002,13 @@ func (l *loggingT) lockAndFlushAll() {
1047
1002
// flushAll flushes all the logs and attempts to "sync" their data to disk.
1048
1003
// l.mu is held.
1049
1004
func (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 ]
1052
1008
if file != nil {
1053
1009
file .Flush () // ignore error
1054
1010
file .Sync () // ignore error
1055
1011
}
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
- }
1065
1012
}
1066
1013
}
1067
1014
@@ -1147,9 +1094,9 @@ type Verbose bool
1147
1094
// The returned value is a boolean of type Verbose, which implements Info, Infoln
1148
1095
// and Infof. These methods will write to the Info log if called.
1149
1096
// Thus, one may write either
1150
- // if glog.V(2) { glog.Info("log this") }
1097
+ // if glog.V(2) { glog.Info("log this") }
1151
1098
// or
1152
- // glog.V(2).Info("log this")
1099
+ // glog.V(2).Info("log this")
1153
1100
// The second form is shorter but the first is cheaper if logging is off because it does
1154
1101
// not evaluate its arguments.
1155
1102
//
0 commit comments