diff --git a/integration/access_log_test.go b/integration/access_log_test.go index 19aef0473..9e950e526 100644 --- a/integration/access_log_test.go +++ b/integration/access_log_test.go @@ -30,7 +30,7 @@ type accessLogValue struct { code string user string frontendName string - backendName string + backendURL string } func (s *AccessLogSuite) SetUpSuite(c *check.C) { @@ -103,7 +103,7 @@ func (s *AccessLogSuite) TestAccessLogAuthFrontend(c *check.C) { code: "401", user: "-", frontendName: "Auth for frontend-Host-frontend-auth-docker-local", - backendName: "-", + backendURL: "/", }, } @@ -151,7 +151,7 @@ func (s *AccessLogSuite) TestAccessLogAuthEntrypoint(c *check.C) { code: "401", user: "-", frontendName: "Auth for entrypoint", - backendName: "-", + backendURL: "/", }, } @@ -199,7 +199,7 @@ func (s *AccessLogSuite) TestAccessLogAuthEntrypointSuccess(c *check.C) { code: "200", user: "test", frontendName: "Host-entrypoint-auth-docker", - backendName: "http://172.17.0", + backendURL: "http://172.17.0", }, } @@ -247,14 +247,14 @@ func (s *AccessLogSuite) TestAccessLogDigestAuthEntrypoint(c *check.C) { code: "401", user: "-", frontendName: "Auth for entrypoint", - backendName: "-", + backendURL: "/", }, { formatOnly: false, code: "200", user: "test", frontendName: "Host-entrypoint-digest-auth-docker", - backendName: "http://172.17.0", + backendURL: "http://172.17.0", }, } @@ -355,7 +355,7 @@ func (s *AccessLogSuite) TestAccessLogEntrypointRedirect(c *check.C) { code: "302", user: "-", frontendName: "entrypoint redirect for frontend-", - backendName: "-", + backendURL: "/", }, { formatOnly: true, @@ -405,7 +405,7 @@ func (s *AccessLogSuite) TestAccessLogFrontendRedirect(c *check.C) { code: "302", user: "-", frontendName: "frontend redirect for frontend-Path-", - backendName: "-", + backendURL: "/", }, { formatOnly: true, @@ -461,7 +461,7 @@ func (s *AccessLogSuite) TestAccessLogRateLimit(c *check.C) { code: "429", user: "-", frontendName: "rate limit for frontend-Host-ratelimit", - backendName: "/", + backendURL: "/", }, } @@ -512,7 +512,7 @@ func (s *AccessLogSuite) TestAccessLogBackendNotFound(c *check.C) { code: "404", user: "-", frontendName: "backend not found", - backendName: "/", + backendURL: "/", }, } @@ -557,7 +557,7 @@ func (s *AccessLogSuite) TestAccessLogEntrypointWhitelist(c *check.C) { code: "403", user: "-", frontendName: "ipwhitelister for entrypoint httpWhitelistReject", - backendName: "-", + backendURL: "/", }, } @@ -604,7 +604,7 @@ func (s *AccessLogSuite) TestAccessLogFrontendWhitelist(c *check.C) { code: "403", user: "-", frontendName: "ipwhitelister for frontend-Host-frontend-whitelist", - backendName: "-", + backendURL: "/", }, } @@ -734,7 +734,7 @@ func checkAccessLogExactValues(c *check.C, line string, i int, v accessLogValue) c.Assert(results[accesslog.OriginStatus], checker.Equals, v.code) c.Assert(results[accesslog.RequestCount], checker.Equals, fmt.Sprintf("%d", i+1)) c.Assert(results[accesslog.FrontendName], checker.Matches, `^"?`+v.frontendName+`.*$`) - c.Assert(results[accesslog.BackendURL], checker.Matches, `^"?`+v.backendName+`.*$`) + c.Assert(results[accesslog.BackendURL], checker.Matches, `^"?`+v.backendURL+`.*$`) c.Assert(results[accesslog.Duration], checker.Matches, `^\d+ms$`) } diff --git a/middlewares/accesslog/save_backend.go b/middlewares/accesslog/save_backend.go index 674656a86..78b503aea 100644 --- a/middlewares/accesslog/save_backend.go +++ b/middlewares/accesslog/save_backend.go @@ -3,15 +3,14 @@ package accesslog import ( "fmt" "net/http" - "strings" "time" "github.com/urfave/negroni" "github.com/vulcand/oxy/utils" ) -// SaveBackend sends the backend name to the logger. These are always used with a corresponding -// SaveFrontend handler. +// SaveBackend sends the backend name to the logger. +// These are always used with a corresponding SaveFrontend handler. type SaveBackend struct { next http.Handler backendName string @@ -23,61 +22,9 @@ func NewSaveBackend(next http.Handler, backendName string) http.Handler { } func (sb *SaveBackend) ServeHTTP(rw http.ResponseWriter, r *http.Request) { - table := GetLogDataTable(r) - table.Core[BackendName] = sb.backendName - table.Core[BackendURL] = r.URL // note that this is *not* the original incoming URL - table.Core[BackendAddr] = r.URL.Host - - crw := &captureResponseWriter{rw: rw} - start := time.Now().UTC() - - sb.next.ServeHTTP(crw, r) - - // use UTC to handle switchover of daylight saving correctly - table.Core[OriginDuration] = time.Now().UTC().Sub(start) - table.Core[OriginStatus] = crw.Status() - table.Core[OriginStatusLine] = fmt.Sprintf("%03d %s", crw.Status(), http.StatusText(crw.Status())) - // make copy of headers so we can ensure there is no subsequent mutation during response processing - table.OriginResponse = make(http.Header) - utils.CopyHeaders(table.OriginResponse, crw.Header()) - table.Core[OriginContentSize] = crw.Size() -} - -// SaveFrontend sends the frontend name to the logger. These are sometimes used with a corresponding -// SaveBackend handler, but not always. For example, redirected requests don't reach a backend. -type SaveFrontend struct { - next http.Handler - frontendName string -} - -// NewSaveFrontend creates a SaveFrontend handler. -func NewSaveFrontend(next http.Handler, frontendName string) http.Handler { - return &SaveFrontend{next, frontendName} -} - -func (sb *SaveFrontend) ServeHTTP(rw http.ResponseWriter, r *http.Request) { - table := GetLogDataTable(r) - table.Core[FrontendName] = strings.TrimPrefix(sb.frontendName, "frontend-") - - sb.next.ServeHTTP(rw, r) -} - -// SaveNegroniFrontend sends the frontend name to the logger. -type SaveNegroniFrontend struct { - next negroni.Handler - frontendName string -} - -// NewSaveNegroniFrontend creates a SaveNegroniFrontend handler. -func NewSaveNegroniFrontend(next negroni.Handler, frontendName string) negroni.Handler { - return &SaveNegroniFrontend{next, frontendName} -} - -func (sb *SaveNegroniFrontend) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { - table := GetLogDataTable(r) - table.Core[FrontendName] = strings.TrimPrefix(sb.frontendName, "frontend-") - - sb.next.ServeHTTP(rw, r, next) + serveSaveBackend(rw, r, sb.backendName, func(crw *captureResponseWriter) { + sb.next.ServeHTTP(crw, r) + }) } // SaveNegroniBackend sends the backend name to the logger. @@ -92,13 +39,21 @@ func NewSaveNegroniBackend(next negroni.Handler, backendName string) negroni.Han } func (sb *SaveNegroniBackend) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { + serveSaveBackend(rw, r, sb.backendName, func(crw *captureResponseWriter) { + sb.next.ServeHTTP(crw, r, next) + }) +} + +func serveSaveBackend(rw http.ResponseWriter, r *http.Request, backendName string, apply func(*captureResponseWriter)) { table := GetLogDataTable(r) - table.Core[BackendName] = sb.backendName + table.Core[BackendName] = backendName + table.Core[BackendURL] = r.URL // note that this is *not* the original incoming URL + table.Core[BackendAddr] = r.URL.Host crw := &captureResponseWriter{rw: rw} start := time.Now().UTC() - sb.next.ServeHTTP(crw, r, next) + apply(crw) // use UTC to handle switchover of daylight saving correctly table.Core[OriginDuration] = time.Now().UTC().Sub(start) diff --git a/middlewares/accesslog/save_frontend.go b/middlewares/accesslog/save_frontend.go new file mode 100644 index 000000000..e256444a5 --- /dev/null +++ b/middlewares/accesslog/save_frontend.go @@ -0,0 +1,51 @@ +package accesslog + +import ( + "net/http" + "strings" + + "github.com/urfave/negroni" +) + +// SaveFrontend sends the frontend name to the logger. +// These are sometimes used with a corresponding SaveBackend handler, but not always. +// For example, redirected requests don't reach a backend. +type SaveFrontend struct { + next http.Handler + frontendName string +} + +// NewSaveFrontend creates a SaveFrontend handler. +func NewSaveFrontend(next http.Handler, frontendName string) http.Handler { + return &SaveFrontend{next, frontendName} +} + +func (sf *SaveFrontend) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + serveSaveFrontend(r, sf.frontendName, func() { + sf.next.ServeHTTP(rw, r) + }) +} + +// SaveNegroniFrontend sends the frontend name to the logger. +type SaveNegroniFrontend struct { + next negroni.Handler + frontendName string +} + +// NewSaveNegroniFrontend creates a SaveNegroniFrontend handler. +func NewSaveNegroniFrontend(next negroni.Handler, frontendName string) negroni.Handler { + return &SaveNegroniFrontend{next, frontendName} +} + +func (sf *SaveNegroniFrontend) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { + serveSaveFrontend(r, sf.frontendName, func() { + sf.next.ServeHTTP(rw, r, next) + }) +} + +func serveSaveFrontend(r *http.Request, frontendName string, apply func()) { + table := GetLogDataTable(r) + table.Core[FrontendName] = strings.TrimPrefix(frontendName, "frontend-") + + apply() +}