TUN-3767: Tolerate logging errors

This addresses a bug where logging would not be output when
cloudflared was run as a Windows Service.

That was happening because Windows Services have no stderr/out,
and the ConsoleWriter log was failing inside zerolog, which would
then not proceed to the next logger (the file logger).

We now overcome that by using our own multi writer that is resilient
to errors.
This commit is contained in:
Nuno Diegues
2021-01-16 15:56:44 +00:00
parent 8da61274b8
commit de27361ffa
2 changed files with 105 additions and 1 deletions

View File

@@ -37,6 +37,21 @@ func fallbackLogger(err error) *zerolog.Logger {
return &failLog
}
type resilientMultiWriter struct {
writers []io.Writer
}
// This custom resilientMultiWriter is an alternative to zerolog's so that we can make it resilient to individual
// writer's errors. E.g., when running as a Windows service, the console writer fails, but we don't want to
// allow that to prevent all logging to fail due to breaking the for loop upon an error.
func (t resilientMultiWriter) Write(p []byte) (n int, err error) {
for _, w := range t.writers {
_, _ = w.Write(p)
}
return len(p), nil
}
func newZerolog(loggerConfig *Config) *zerolog.Logger {
var writers []io.Writer
@@ -62,7 +77,7 @@ func newZerolog(loggerConfig *Config) *zerolog.Logger {
writers = append(writers, rollingLogger)
}
multi := zerolog.MultiLevelWriter(writers...)
multi := resilientMultiWriter{writers}
level, err := zerolog.ParseLevel(loggerConfig.MinLevel)
if err != nil {