@@ -703,7 +703,16 @@ func (l *loggingT) output(s severity, buf *buffer, file string, line int, alsoTo
703703 }
704704 }
705705 if s == fatalLog {
706- // Make sure we see the trace for the current goroutine on standard error.
706+ // If we got here via Exit rather than Fatal, print no stacks.
707+ if atomic .LoadUint32 (& fatalNoStacks ) > 0 {
708+ l .mu .Unlock ()
709+ timeoutFlush (10 * time .Second )
710+ os .Exit (1 )
711+ }
712+ // Dump all goroutine stacks before exiting.
713+ // First, make sure we see the trace for the current goroutine on standard error.
714+ // If -logtostderr has been specified, the loop below will do that anyway
715+ // as the first stack in the full dump.
707716 if ! l .toStderr {
708717 os .Stderr .Write (stacks (false ))
709718 }
@@ -1135,3 +1144,34 @@ func Fatalln(args ...interface{}) {
11351144func Fatalf (format string , args ... interface {}) {
11361145 logging .printf (fatalLog , format , args ... )
11371146}
1147+
1148+ // fatalNoStacks is non-zero if we are to exit without dumping goroutine stacks.
1149+ // It allows Exit and relatives to use the Fatal logs.
1150+ var fatalNoStacks uint32
1151+
1152+ // Exit logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
1153+ // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
1154+ func Exit (args ... interface {}) {
1155+ atomic .StoreUint32 (& fatalNoStacks , 1 )
1156+ logging .print (fatalLog , args ... )
1157+ }
1158+
1159+ // ExitDepth acts as Exit but uses depth to determine which call frame to log.
1160+ // ExitDepth(0, "msg") is the same as Exit("msg").
1161+ func ExitDepth (depth int , args ... interface {}) {
1162+ atomic .StoreUint32 (& fatalNoStacks , 1 )
1163+ logging .printDepth (fatalLog , depth , args ... )
1164+ }
1165+
1166+ // Exitln logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
1167+ func Exitln (args ... interface {}) {
1168+ atomic .StoreUint32 (& fatalNoStacks , 1 )
1169+ logging .println (fatalLog , args ... )
1170+ }
1171+
1172+ // Exitf logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
1173+ // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
1174+ func Exitf (format string , args ... interface {}) {
1175+ atomic .StoreUint32 (& fatalNoStacks , 1 )
1176+ logging .printf (fatalLog , format , args ... )
1177+ }
0 commit comments