Rename module path github.com/ryanhamamura/c4 to github.com/ryanhamamura/games across go.mod, all source files, and golangci config.
127 lines
2.5 KiB
Go
127 lines
2.5 KiB
Go
package logging
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/ryanhamamura/games/config"
|
|
|
|
"github.com/rs/zerolog"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
const (
|
|
ansiReset = "\033[0m"
|
|
ansiBrightRed = "\033[31;1m"
|
|
ansiBrightGreen = "\033[32;1m"
|
|
ansiBrightYellow = "\033[33;1m"
|
|
ansiBrightMagenta = "\033[35;1m"
|
|
ansiBrightCyan = "\033[36;1m"
|
|
ansiGreen = "\033[32m"
|
|
ansiYellow = "\033[33m"
|
|
ansiRed = "\033[31m"
|
|
)
|
|
|
|
func colorStatus(status int, useColor bool) string {
|
|
s := fmt.Sprintf("%d", status)
|
|
if !useColor {
|
|
return s
|
|
}
|
|
switch {
|
|
case status < 200:
|
|
return ansiBrightGreen + s + ansiReset
|
|
case status < 300:
|
|
return ansiBrightGreen + s + ansiReset
|
|
case status < 400:
|
|
return ansiBrightCyan + s + ansiReset
|
|
case status < 500:
|
|
return ansiBrightYellow + s + ansiReset
|
|
default:
|
|
return ansiBrightRed + s + ansiReset
|
|
}
|
|
}
|
|
|
|
func colorMethod(method string, useColor bool) string {
|
|
if !useColor {
|
|
return method
|
|
}
|
|
return ansiBrightMagenta + method + ansiReset
|
|
}
|
|
|
|
func colorLatency(d time.Duration, useColor bool) string {
|
|
s := d.String()
|
|
if !useColor {
|
|
return s
|
|
}
|
|
switch {
|
|
case d < 500*time.Millisecond:
|
|
return ansiGreen + s + ansiReset
|
|
case d < 5*time.Second:
|
|
return ansiYellow + s + ansiReset
|
|
default:
|
|
return ansiRed + s + ansiReset
|
|
}
|
|
}
|
|
|
|
type responseWriter struct {
|
|
http.ResponseWriter
|
|
status int
|
|
}
|
|
|
|
func (rw *responseWriter) WriteHeader(code int) {
|
|
rw.status = code
|
|
rw.ResponseWriter.WriteHeader(code)
|
|
}
|
|
|
|
func RequestLogger(logger *zerolog.Logger, env config.Environment) func(http.Handler) http.Handler {
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
start := time.Now()
|
|
rw := &responseWriter{ResponseWriter: w}
|
|
|
|
next.ServeHTTP(rw, r)
|
|
|
|
status := rw.status
|
|
if status == 0 {
|
|
status = http.StatusOK
|
|
}
|
|
l := log.Ctx(r.Context())
|
|
if l.GetLevel() == zerolog.Disabled {
|
|
l = logger
|
|
}
|
|
|
|
var evt *zerolog.Event
|
|
switch {
|
|
case status < 400:
|
|
evt = l.Info()
|
|
case status < 500:
|
|
evt = l.Warn()
|
|
case status < 600:
|
|
evt = l.Error()
|
|
default:
|
|
evt = l.Info()
|
|
}
|
|
|
|
latency := time.Since(start)
|
|
switch env {
|
|
case config.Dev:
|
|
useColor := true
|
|
evt.Msg(fmt.Sprintf("%s %s %s [%s]",
|
|
colorStatus(status, useColor),
|
|
colorMethod(r.Method, useColor),
|
|
r.URL.Path,
|
|
colorLatency(latency, useColor),
|
|
))
|
|
default:
|
|
evt.
|
|
Int("status", status).
|
|
Str("method", r.Method).
|
|
Str("path", r.URL.Path).
|
|
Dur("latency", latency).
|
|
Msg("request")
|
|
}
|
|
})
|
|
}
|
|
}
|