From 7dbfea1353fc292d20cd399305edf00e4b91f105 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Fri, 22 May 2020 21:59:18 -0700 Subject: [PATCH] avoid net/http ErrorLog for consistent logging experience (#9672) net/http exposes ErrorLog but it is log.Logger instance not an interface which can be overridden, because of this reason the logging is interleaved sometimes with TLS with messages like this on the server ``` http: TLS handshake error from 139.178.70.188:63760: EOF ``` This is bit problematic for us as we need to have consistent logging view for allow --json or --quiet flags. With this PR we ensure that this format is adhered to. --- cmd/server-main.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/cmd/server-main.go b/cmd/server-main.go index 42cc794e2..1c67f8f39 100644 --- a/cmd/server-main.go +++ b/cmd/server-main.go @@ -17,9 +17,12 @@ package cmd import ( + "bufio" "context" "errors" "fmt" + "io" + "log" "net" "net/http" "os" @@ -450,7 +453,27 @@ func serverMain(ctx *cli.Context) { getCert = globalTLSCerts.GetCertificate } + // Annonying hack to ensure that Go doesn't write its own logging, + // interleaved with our formatted logging, this allows us to + // honor --json and --quiet flag properly. + // + // Unfortunately we have to resort to this sort of hacky approach + // because, Go automatically initializes ErrorLog on its own + // and can log without application control. + // + // This is an implementation issue in Go and should be fixed, but + // until then this hack is okay and works for our needs. + pr, pw := io.Pipe() + go func() { + defer pr.Close() + scanner := bufio.NewScanner(&contextReader{pr, GlobalContext}) + for scanner.Scan() { + logger.LogIf(GlobalContext, errors.New(scanner.Text())) + } + }() + httpServer := xhttp.NewServer([]string{globalMinioAddr}, criticalErrorHandler{handler}, getCert) + httpServer.ErrorLog = log.New(pw, "", 0) httpServer.BaseContext = func(listener net.Listener) context.Context { return GlobalContext }