From c9735476a7ab748346f8da95d005beb3cdc3802d Mon Sep 17 00:00:00 2001 From: "Chris S. Kim" Date: Thu, 6 Jan 2022 16:07:09 -0500 Subject: [PATCH] Fix Windows logging to files (#11960) --- .changelog/11960.txt | 3 +++ logging/logger.go | 24 +++++++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 .changelog/11960.txt diff --git a/.changelog/11960.txt b/.changelog/11960.txt new file mode 100644 index 000000000..aac5bd422 --- /dev/null +++ b/.changelog/11960.txt @@ -0,0 +1,3 @@ +```release-note:bug +windows: Fixes a bug with empty log files when Consul is run as a Windows Service +``` \ No newline at end of file diff --git a/logging/logger.go b/logging/logger.go index dfc05785c..9d6cff74f 100644 --- a/logging/logger.go +++ b/logging/logger.go @@ -27,16 +27,16 @@ type Config struct { // SyslogFacility is the destination for syslog forwarding. SyslogFacility string - //LogFilePath is the path to write the logs to the user specified file. + // LogFilePath is the path to write the logs to the user specified file. LogFilePath string - //LogRotateDuration is the user specified time to rotate logs + // LogRotateDuration is the user specified time to rotate logs LogRotateDuration time.Duration - //LogRotateBytes is the user specified byte limit to rotate logs + // LogRotateBytes is the user specified byte limit to rotate logs LogRotateBytes int - //LogRotateMaxFiles is the maximum number of past archived log files to keep + // LogRotateMaxFiles is the maximum number of past archived log files to keep LogRotateMaxFiles int } @@ -45,6 +45,17 @@ const defaultRotateDuration = 24 * time.Hour type LogSetupErrorFn func(string) +// noErrorWriter is a wrapper to suppress errors when writing to w. +type noErrorWriter struct { + w io.Writer +} + +func (w noErrorWriter) Write(p []byte) (n int, err error) { + _, _ = w.w.Write(p) + // We purposely return n == len(p) as if write was successful + return len(p), nil +} + // Setup logging from Config, and return an hclog Logger. // // Logs may be written to out, and optionally to syslog, and a file. @@ -55,7 +66,10 @@ func Setup(config Config, out io.Writer) (hclog.InterceptLogger, error) { allowedLogLevels) } - writers := []io.Writer{out} + // If out is os.Stdout and Consul is being run as a Windows Service, writes will + // fail silently, which may inadvertently prevent writes to other writers. + // noErrorWriter is used as a wrapper to suppress any errors when writing to out. + writers := []io.Writer{noErrorWriter{w: out}} if config.EnableSyslog { retries := 12