mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-03 18:20:27 +00:00
Add middleware for logging each request to the app.
This commit is contained in:
45
common/middleware/logging.go
Normal file
45
common/middleware/logging.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Logging middleware logs each HTTP request method, path, response code and duration.
|
||||
var Logging = Func(func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
begin := time.Now()
|
||||
i := &interceptor{ResponseWriter: w, statusCode: http.StatusOK}
|
||||
next.ServeHTTP(i, r)
|
||||
log.Infof("%s %s (%d) %s", r.Method, r.RequestURI, i.statusCode, time.Since(begin))
|
||||
})
|
||||
})
|
||||
|
||||
// interceptor implements WriteHeader to intercept status codes. WriteHeader
|
||||
// may not be called on success, so initialize statusCode with the status you
|
||||
// want to report on success, i.e. http.StatusOK.
|
||||
//
|
||||
// interceptor also implements net.Hijacker, to let the downstream Handler
|
||||
// hijack the connection. This is needed by the app-mapper's proxy.
|
||||
type interceptor struct {
|
||||
http.ResponseWriter
|
||||
statusCode int
|
||||
}
|
||||
|
||||
func (i *interceptor) WriteHeader(code int) {
|
||||
i.statusCode = code
|
||||
i.ResponseWriter.WriteHeader(code)
|
||||
}
|
||||
|
||||
func (i *interceptor) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||
hj, ok := i.ResponseWriter.(http.Hijacker)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("interceptor: can't cast parent ResponseWriter to Hijacker")
|
||||
}
|
||||
return hj.Hijack()
|
||||
}
|
||||
30
common/middleware/middleware.go
Normal file
30
common/middleware/middleware.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Interface is the shared contract for all middlesware, and allows middlesware
|
||||
// to wrap handlers.
|
||||
type Interface interface {
|
||||
Wrap(http.Handler) http.Handler
|
||||
}
|
||||
|
||||
// Func is to Interface as http.HandlerFunc is to http.Handler
|
||||
type Func func(http.Handler) http.Handler
|
||||
|
||||
// Wrap implements Interface
|
||||
func (m Func) Wrap(next http.Handler) http.Handler {
|
||||
return m(next)
|
||||
}
|
||||
|
||||
// Merge produces a middleware that applies multiple middlesware in turn;
|
||||
// ie Merge(f,g,h).Wrap(handler) == f.Wrap(g.Wrap(h.Wrap(handler)))
|
||||
func Merge(middlesware ...Interface) Interface {
|
||||
return Func(func(next http.Handler) http.Handler {
|
||||
for i := len(middlesware) - 1; i >= 0; i-- {
|
||||
next = middlesware[i].Wrap(next)
|
||||
}
|
||||
return next
|
||||
})
|
||||
}
|
||||
13
prog/app.go
13
prog/app.go
@@ -20,6 +20,7 @@ import (
|
||||
|
||||
"github.com/weaveworks/scope/app"
|
||||
"github.com/weaveworks/scope/app/multitenant"
|
||||
"github.com/weaveworks/scope/common/middleware"
|
||||
"github.com/weaveworks/scope/common/weave"
|
||||
"github.com/weaveworks/scope/common/xfer"
|
||||
"github.com/weaveworks/scope/probe/docker"
|
||||
@@ -110,10 +111,11 @@ func pipeRouterFactory(userIDer multitenant.UserIDer, pipeRouterURL, consulInf s
|
||||
// Main runs the app
|
||||
func appMain() {
|
||||
var (
|
||||
window = flag.Duration("window", 15*time.Second, "window")
|
||||
listen = flag.String("http.address", ":"+strconv.Itoa(xfer.AppPort), "webserver listen address")
|
||||
logLevel = flag.String("log.level", "info", "logging threshold level: debug|info|warn|error|fatal|panic")
|
||||
logPrefix = flag.String("log.prefix", "<app>", "prefix for each log line")
|
||||
window = flag.Duration("window", 15*time.Second, "window")
|
||||
listen = flag.String("http.address", ":"+strconv.Itoa(xfer.AppPort), "webserver listen address")
|
||||
logLevel = flag.String("log.level", "info", "logging threshold level: debug|info|warn|error|fatal|panic")
|
||||
logPrefix = flag.String("log.prefix", "<app>", "prefix for each log line")
|
||||
logRequests = flag.Bool("log.requests", false, "Log individual HTTP requests")
|
||||
|
||||
weaveAddr = flag.String("weave.addr", app.DefaultWeaveURL, "Address on which to contact WeaveDNS")
|
||||
weaveHostname = flag.String("weave.hostname", app.DefaultHostname, "Hostname to advertise in WeaveDNS")
|
||||
@@ -189,6 +191,9 @@ func appMain() {
|
||||
}
|
||||
|
||||
handler := router(collector, controlRouter, pipeRouter)
|
||||
if *logRequests {
|
||||
handler = middleware.Logging.Wrap(handler)
|
||||
}
|
||||
go func() {
|
||||
log.Infof("listening on %s", *listen)
|
||||
log.Info(http.ListenAndServe(*listen, handler))
|
||||
|
||||
Reference in New Issue
Block a user