diff --git a/pkg/apiserver/watch.go b/pkg/apiserver/watch.go index 771682087d..38b3ace500 100644 --- a/pkg/apiserver/watch.go +++ b/pkg/apiserver/watch.go @@ -133,18 +133,18 @@ func (self *WatchServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { cn, ok := w.(http.CloseNotifier) if !ok { loggedW.Addf("unable to get CloseNotifier") - http.NotFound(loggedW, req) + http.NotFound(w, req) return } flusher, ok := w.(http.Flusher) if !ok { loggedW.Addf("unable to get Flusher") - http.NotFound(loggedW, req) + http.NotFound(w, req) return } - loggedW.Header().Set("Transfer-Encoding", "chunked") - loggedW.WriteHeader(http.StatusOK) + w.Header().Set("Transfer-Encoding", "chunked") + w.WriteHeader(http.StatusOK) flusher.Flush() encoder := json.NewEncoder(w) diff --git a/pkg/httplog/log.go b/pkg/httplog/log.go index 912625b7eb..c964e3864c 100644 --- a/pkg/httplog/log.go +++ b/pkg/httplog/log.go @@ -40,6 +40,10 @@ func Handler(delegate http.Handler, pred StacktracePred) http.Handler { // StacktracePred returns true if a stacktrace should be logged for this status. type StacktracePred func(httpStatus int) (logStacktrace bool) +type logger interface { + Addf(format string, data ...interface{}) +} + // Add a layer on top of ResponseWriter, so we can track latency and error // message sources. type respLogger struct { @@ -54,6 +58,14 @@ type respLogger struct { logStacktracePred StacktracePred } +// Simple logger that logs immediately when Addf is called +type passthroughLogger struct{} + +// Addf logs info immediately. +func (passthroughLogger) Addf(format string, data ...interface{}) { + glog.Infof(format, data...) +} + // DefaultStacktracePred is the default implementation of StacktracePred. func DefaultStacktracePred(status int) bool { return status < http.StatusOK || status >= http.StatusBadRequest @@ -87,11 +99,12 @@ func NewLogged(req *http.Request, w *http.ResponseWriter) *respLogger { } // LogOf returns the logger hiding in w. If there is not an existing logger -// then one will be created because NewLogged() must have been previously -// called for the log to work. -func LogOf(req *http.Request, w http.ResponseWriter) *respLogger { +// then a passthroughLogger will be created which will log to stdout immediately +// when Addf is called. +func LogOf(req *http.Request, w http.ResponseWriter) logger { if _, exists := w.(*respLogger); !exists { - NewLogged(req, &w) + pl := &passthroughLogger{} + return pl } if rl, ok := w.(*respLogger); ok { return rl diff --git a/pkg/httplog/log_test.go b/pkg/httplog/log_test.go index 0ae8f53cde..aea79ab545 100644 --- a/pkg/httplog/log_test.go +++ b/pkg/httplog/log_test.go @@ -91,12 +91,16 @@ func TestLogOf(t *testing.T) { t.Errorf("Unexpected error: %v", err) } handler := func(w http.ResponseWriter, r *http.Request) { + var want string if makeLogger { NewLogged(req, &w) + want = "*httplog.respLogger" + } else { + want = "*httplog.passthroughLogger" } - got := reflect.TypeOf(*LogOf(r, w)).String() - if got != "httplog.respLogger" { - t.Errorf("Expected %v, got %v", "httplog.respLogger", got) + got := reflect.TypeOf(LogOf(r, w)).String() + if want != got { + t.Errorf("Expected %v, got %v", want, got) } } w := httptest.NewRecorder()