grim/hgkeeper

dc46af0b583b
Spit out a warning if we find a duplicated key.

We're going to continue the existing behavior of overwriting the keys to not
break potential set ups for the time being.

Fixes HGKEEPER-22
package http
import (
"net/http"
"strings"
"time"
log "github.com/sirupsen/logrus"
)
type loggerResponseWriter struct {
w http.ResponseWriter
wroteHeader bool
statusCode int
written int64
}
var _ http.ResponseWriter = (*loggerResponseWriter)(nil)
func (w *loggerResponseWriter) Header() http.Header {
return w.w.Header()
}
func (w *loggerResponseWriter) Write(data []byte) (int, error) {
if !w.wroteHeader {
w.WriteHeader(http.StatusOK)
}
n, err := w.w.Write(data)
w.written += int64(n)
return n, err
}
func (w *loggerResponseWriter) WriteHeader(statusCode int) {
if !w.wroteHeader {
w.statusCode = statusCode
w.wroteHeader = true
}
w.w.WriteHeader(w.statusCode)
}
func (w *loggerResponseWriter) StatusCode() int {
return w.statusCode
}
func (w *loggerResponseWriter) Written() int64 {
return w.written
}
func getAddr(r *http.Request) string {
// check for the X-Forwarded-For header and use if it we have it
if fwd := r.Header.Get("X-Forwarded-For"); fwd != "" {
return fwd
}
// Request.RemoteAddr is ipv4:port or [ipv6]:port so we have to trim off
// the extra bits.
addr := r.RemoteAddr
// we use LastIndex so we can parse IPv6 addresses
if idx := strings.LastIndex(addr, ":"); idx != -1 {
addr = addr[:idx]
}
// if the ipv6 was wrapped in [] we need to unwrap it
if idx := strings.Index(addr, "]"); idx != -1 {
addr = addr[1:idx]
}
return addr
}
func Logger(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
rw := &loggerResponseWriter{
w: w,
}
defer func() {
// implement the NCSA Combined Log Format
// http://publib.boulder.ibm.com/tividd/td/ITWSA/ITWSA_info45/en_US/HTML/guide/c-logs.html#combined
addr := getAddr(r)
username := "-"
if user, _, ok := r.BasicAuth(); ok && username != "" {
username = user
}
referer := r.Referer()
if referer == "" {
referer = "-"
}
userAgent := r.UserAgent()
if userAgent == "" {
userAgent = "-"
}
log.Infof(
"%s - %s [%s] \"%s %s %s\" %d %d %q %q\n",
addr,
username,
time.Now().Format("02/Jan/2006:15:04:05 -0700"),
r.Method,
r.URL.Path,
r.Proto,
rw.StatusCode(),
rw.Written(),
referer,
userAgent,
)
}()
h.ServeHTTP(rw, r)
})
}