diff --git a/cmd/common-main.go b/cmd/common-main.go index 1faaf6cf8..98e0d2356 100644 --- a/cmd/common-main.go +++ b/cmd/common-main.go @@ -102,7 +102,12 @@ func handleCommonEnvVars() { globalIsBrowserEnabled = bool(browserFlag) } - globalHTTPTrace = os.Getenv("MINIO_HTTP_TRACE") != "" + traceFile := os.Getenv("MINIO_HTTP_TRACE") + if traceFile != "" { + var err error + globalHTTPTraceFile, err = os.OpenFile(traceFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0660) + fatalIf(err, "error opening file %s", traceFile) + } globalDomainName = os.Getenv("MINIO_DOMAIN") if globalDomainName != "" { diff --git a/cmd/globals.go b/cmd/globals.go index 889510ed1..4e0b842e7 100644 --- a/cmd/globals.go +++ b/cmd/globals.go @@ -123,8 +123,8 @@ var ( globalHTTPServerErrorCh = make(chan error) globalOSSignalCh = make(chan os.Signal, 1) - // Enable HTTP request/response headers and body logging. - globalHTTPTrace bool + // File to log HTTP request/response headers and body. + globalHTTPTraceFile *os.File // List of admin peers. globalAdminPeers = adminPeers{} diff --git a/cmd/handler-utils.go b/cmd/handler-utils.go index 7dd137798..24b4ca591 100644 --- a/cmd/handler-utils.go +++ b/cmd/handler-utils.go @@ -22,7 +22,6 @@ import ( "net" "net/http" "net/url" - "os" "strings" "github.com/minio/minio/pkg/errors" @@ -251,18 +250,18 @@ func extractPostPolicyFormValues(form *multipart.Form) (filePart io.ReadCloser, // Log headers and body. func httpTraceAll(f http.HandlerFunc) http.HandlerFunc { - if !globalHTTPTrace { + if globalHTTPTraceFile == nil { return f } - return httptracer.TraceReqHandlerFunc(f, os.Stdout, true) + return httptracer.TraceReqHandlerFunc(f, globalHTTPTraceFile, true) } // Log only the headers. func httpTraceHdrs(f http.HandlerFunc) http.HandlerFunc { - if !globalHTTPTrace { + if globalHTTPTraceFile == nil { return f } - return httptracer.TraceReqHandlerFunc(f, os.Stdout, false) + return httptracer.TraceReqHandlerFunc(f, globalHTTPTraceFile, false) } // Returns "/bucketName/objectName" for path-style or virtual-host-style requests. diff --git a/cmd/signals.go b/cmd/signals.go index 59ba40529..9739fcc47 100644 --- a/cmd/signals.go +++ b/cmd/signals.go @@ -61,6 +61,7 @@ func handleSignals() { exit(err == nil && oerr == nil) case osSignal := <-globalOSSignalCh: + stopHTTPTrace() log.Printf("Exiting on signal %v\n", osSignal) exit(stopProcess()) case signal := <-globalServiceSignalCh: @@ -71,12 +72,14 @@ func handleSignals() { log.Println("Restarting on service signal") err := globalHTTPServer.Shutdown() errorIf(err, "Unable to shutdown http server") + stopHTTPTrace() rerr := restartProcess() errorIf(rerr, "Unable to restart the server") exit(err == nil && rerr == nil) case serviceStop: log.Println("Stopping on service signal") + stopHTTPTrace() exit(stopProcess()) } } diff --git a/cmd/utils.go b/cmd/utils.go index 2171297fe..74b05f642 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -37,6 +37,14 @@ import ( "github.com/pkg/profile" ) +// Close Http tracing file. +func stopHTTPTrace() { + if globalHTTPTraceFile != nil { + errorIf(globalHTTPTraceFile.Close(), "Unable to close httpTraceFile %s", globalHTTPTraceFile.Name()) + globalHTTPTraceFile = nil + } +} + // make a copy of http.Header func cloneHeader(h http.Header) http.Header { h2 := make(http.Header, len(h)) diff --git a/cmd/utils_test.go b/cmd/utils_test.go index 9d7980f73..db7dbd6e7 100644 --- a/cmd/utils_test.go +++ b/cmd/utils_test.go @@ -19,8 +19,10 @@ package cmd import ( "encoding/json" "errors" + "io/ioutil" "net/http" "net/url" + "os" "reflect" "strings" "testing" @@ -50,6 +52,19 @@ func TestCloneHeader(t *testing.T) { } } +// Tests closing http tracing file. +func TestStopHTTPTrace(t *testing.T) { + var err error + globalHTTPTraceFile, err = ioutil.TempFile("", "") + if err != nil { + defer os.Remove(globalHTTPTraceFile.Name()) + stopHTTPTrace() + if globalHTTPTraceFile != nil { + t.Errorf("globalHTTPTraceFile is not nil, it is expected to be nil") + } + } +} + // Tests maximum object size. func TestMaxObjectSize(t *testing.T) { sizes := []struct {