Skip to content

Commit 2b790ef

Browse files
authored
glog: generate a Fatalf-like error message when writing to logsinks fails (#76)
Writing to logsinks can fail (for example due to "no space left on device" or I/O errors). When that happens glog has no reasonable way to continue and causes the program to exit with exit status 2. Previously glog reused the metadata of the current call to print an error message, but that was problematic. Depending on the current call's log severity it's possible that the program just exited without printing anything. That's confusing and hard to debug. To fix that, glog creates now a new FATAL-level metadata object and prints a clearer error message (with stacks). In most situations this will at least be logged to stderr. Thanks @atetubou for the initial fix! cl/750790337 (google-internal) cl/752634801 (google-internal)
1 parent a0e3c40 commit 2b790ef

File tree

1 file changed

+20
-3
lines changed

1 file changed

+20
-3
lines changed

glog.go

+20-3
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ func ctxlogf(ctx context.Context, depth int, severity logsink.Severity, verbose
238238
metaPool.Put(metai)
239239
}
240240

241+
var sinkErrOnce sync.Once
242+
241243
func sinkf(meta *logsink.Meta, format string, args ...any) {
242244
meta.Depth++
243245
n, err := logsink.Printf(meta, format, args...)
@@ -247,9 +249,20 @@ func sinkf(meta *logsink.Meta, format string, args ...any) {
247249
}
248250

249251
if err != nil {
250-
logsink.Printf(meta, "glog: exiting because of error: %s", err)
251-
sinks.file.Flush()
252-
os.Exit(2)
252+
// Best-effort to generate a reasonable Fatalf-like
253+
// error message in all sinks that are still here for
254+
// the first goroutine that comes here and terminate
255+
// the process.
256+
sinkErrOnce.Do(func() {
257+
m := &logsink.Meta{}
258+
m.Time = timeNow()
259+
m.Severity = logsink.Fatal
260+
m.Thread = int64(pid)
261+
_, m.File, m.Line, _ = runtime.Caller(0)
262+
format, args := appendBacktrace(1, "log: exiting because of error writing previous log to sinks: %v", []any{err})
263+
logsink.Printf(m, format, args...)
264+
flushAndAbort()
265+
})
253266
}
254267
}
255268

@@ -642,6 +655,10 @@ func ErrorContextDepthf(ctx context.Context, depth int, format string, args ...a
642655

643656
func ctxfatalf(ctx context.Context, depth int, format string, args ...any) {
644657
ctxlogf(ctx, depth+1, logsink.Fatal, false, withStack, format, args...)
658+
flushAndAbort()
659+
}
660+
661+
func flushAndAbort() {
645662
sinks.file.Flush()
646663

647664
err := abortProcess() // Should not return.

0 commit comments

Comments
 (0)