0
Fork 0
mirror of https://github.com/project-zot/zot.git synced 2024-12-16 21:56:37 -05:00
zot/pkg/log/log.go

117 lines
2.3 KiB
Go
Raw Normal View History

package log
2019-06-20 18:36:40 -05:00
import (
"net/http"
2019-06-20 18:36:40 -05:00
"os"
"time"
"github.com/gorilla/mux"
2019-06-20 18:36:40 -05:00
"github.com/rs/zerolog"
)
// Logger extends zerolog's Logger.
type Logger struct {
zerolog.Logger
}
func (l Logger) Println(v ...interface{}) {
l.Logger.Error().Msg("panic recovered")
}
func NewLogger(level string, output string) Logger {
2019-06-20 18:36:40 -05:00
zerolog.TimeFieldFormat = time.RFC3339Nano
lvl, err := zerolog.ParseLevel(level)
2019-06-20 18:36:40 -05:00
if err != nil {
panic(err)
}
2019-06-20 18:36:40 -05:00
zerolog.SetGlobalLevel(lvl)
2019-06-20 18:36:40 -05:00
var log zerolog.Logger
if output == "" {
2019-06-20 18:36:40 -05:00
log = zerolog.New(os.Stdout)
} else {
file, err := os.OpenFile(output, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
2019-06-20 18:36:40 -05:00
if err != nil {
panic(err)
}
log = zerolog.New(file)
}
return Logger{Logger: log.With().Caller().Timestamp().Logger()}
2019-06-20 18:36:40 -05:00
}
type statusWriter struct {
http.ResponseWriter
status int
length int
}
func (w *statusWriter) WriteHeader(status int) {
w.status = status
w.ResponseWriter.WriteHeader(status)
}
func (w *statusWriter) Write(b []byte) (int, error) {
if w.status == 0 {
w.status = 200
}
n, err := w.ResponseWriter.Write(b)
w.length += n
return n, err
}
func SessionLogger(log Logger) mux.MiddlewareFunc {
2019-06-20 18:36:40 -05:00
l := log.With().Str("module", "http").Logger()
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Start timer
start := time.Now()
path := r.URL.Path
raw := r.URL.RawQuery
2019-06-20 18:36:40 -05:00
sw := statusWriter{ResponseWriter: w}
2019-06-20 18:36:40 -05:00
// Process request
next.ServeHTTP(&sw, r)
// Stop timer
end := time.Now()
latency := end.Sub(start)
if latency > time.Minute {
// Truncate in a golang < 1.8 safe way
latency -= latency % time.Second
}
clientIP := r.RemoteAddr
method := r.Method
2019-10-24 16:16:41 -05:00
headers := map[string][]string{}
for key, value := range r.Header {
if key == "Authorization" { // anonymize from logs
value = []string{"******"}
}
headers[key] = value
}
statusCode := sw.status
bodySize := sw.length
if raw != "" {
path = path + "?" + raw
}
2019-06-20 18:36:40 -05:00
l.Info().
Str("clientIP", clientIP).
Str("method", method).
Str("path", path).
Int("statusCode", statusCode).
Str("latency", latency.String()).
Int("bodySize", bodySize).
Interface("headers", headers).
Msg("HTTP API")
})
2019-06-20 18:36:40 -05:00
}
}