Files
gluetun/internal/server/log.go
Quentin McGaw 4257581f55 Loops and HTTP control server rework (#308)
- CRUD REST HTTP server
- `/v1` HTTP server prefix
- Retrocompatible with older routes (redirects to v1 or handles the requests directly)
- DNS, Updater and Openvpn refactored to have a REST-like state with new methods to change their states synchronously
- Openvpn, Unbound and Updater status, see #287
2020-12-19 20:10:34 -05:00

76 lines
1.7 KiB
Go

package server
import (
"net/http"
"sync"
"time"
"github.com/qdm12/golibs/logging"
)
func withLogMiddleware(childHandler http.Handler, logger logging.Logger, enabled bool) *logMiddleware {
return &logMiddleware{
childHandler: childHandler,
logger: logger,
timeNow: time.Now,
enabled: enabled,
}
}
type logMiddleware struct {
childHandler http.Handler
logger logging.Logger
timeNow func() time.Time
enabled bool
enabledMu sync.RWMutex
}
func (m *logMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if !m.isEnabled() {
m.childHandler.ServeHTTP(w, r)
return
}
tStart := m.timeNow()
statefulWriter := &statefulResponseWriter{httpWriter: w}
m.childHandler.ServeHTTP(statefulWriter, r)
duration := m.timeNow().Sub(tStart)
m.logger.Info("%d %s %s wrote %dB to %s in %s",
statefulWriter.statusCode, r.Method, r.RequestURI, statefulWriter.length, r.RemoteAddr, duration)
}
func (m *logMiddleware) setEnabled(enabled bool) {
m.enabledMu.Lock()
defer m.enabledMu.Unlock()
m.enabled = enabled
}
func (m *logMiddleware) isEnabled() (enabled bool) {
m.enabledMu.RLock()
defer m.enabledMu.RUnlock()
return m.enabled
}
type statefulResponseWriter struct {
httpWriter http.ResponseWriter
statusCode int
length int
}
func (w *statefulResponseWriter) Write(b []byte) (n int, err error) {
n, err = w.httpWriter.Write(b)
if w.statusCode == 0 {
w.statusCode = http.StatusOK
}
w.length += n
return n, err
}
func (w *statefulResponseWriter) WriteHeader(statusCode int) {
w.statusCode = statusCode
w.httpWriter.WriteHeader(statusCode)
}
func (w *statefulResponseWriter) Header() http.Header {
return w.httpWriter.Header()
}