Merge branch 'master' into 3454-default-docker-image
[arvados.git] / services / keepstore / logging_router.go
1 package main
2
3 // LoggingRESTRouter
4 // LoggingResponseWriter
5
6 import (
7         "github.com/gorilla/mux"
8         "log"
9         "net/http"
10         "strings"
11         "time"
12 )
13
14 type LoggingResponseWriter struct {
15         Status int
16         Length int
17         http.ResponseWriter
18         ResponseBody string
19 }
20
21 func (loggingWriter *LoggingResponseWriter) WriteHeader(code int) {
22         loggingWriter.Status = code
23         loggingWriter.ResponseWriter.WriteHeader(code)
24 }
25
26 func (loggingWriter *LoggingResponseWriter) Write(data []byte) (int, error) {
27         loggingWriter.Length += len(data)
28         if loggingWriter.Status >= 400 {
29                 loggingWriter.ResponseBody += string(data)
30         }
31         return loggingWriter.ResponseWriter.Write(data)
32 }
33
34 type LoggingRESTRouter struct {
35         router *mux.Router
36 }
37
38 func MakeLoggingRESTRouter() *LoggingRESTRouter {
39         router := MakeRESTRouter()
40         return (&LoggingRESTRouter{router})
41 }
42
43 func (loggingRouter *LoggingRESTRouter) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
44         t0 := time.Now()
45         loggingWriter := LoggingResponseWriter{http.StatusOK, 0, resp, ""}
46         loggingRouter.router.ServeHTTP(&loggingWriter, req)
47         statusText := http.StatusText(loggingWriter.Status)
48         if loggingWriter.Status >= 400 {
49                 statusText = strings.Replace(loggingWriter.ResponseBody, "\n", "", -1)
50         }
51         log.Printf("[%s] %s %s %.6fs %d %d \"%s\"", req.RemoteAddr, req.Method, req.URL.Path[1:], time.Since(t0).Seconds(), loggingWriter.Status, loggingWriter.Length, statusText)
52
53 }