feat(logging): integrate slog logging with env control and request/sync tracing
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 39s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 39s
- Configure structured slog logger in cmd/server/main.go via LOG_LEVEL and DEBUG env vars - Add HTTP API request logging middleware in internal/api/ with status and duration_ms - Add WebSocket join/leave, event reception, and debounced SQLite flush tracing in docroom - Document LOG_LEVEL and DEBUG settings in .env.example, compose.yaml, and docker-compose.yml
This commit is contained in:
1 parent
177e24fdc8
commit
48fe61fbce
9 files changed
+208
-16
No files matched your search
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"net/smtp"
|
||||
"strings"
|
||||
@@ -48,6 +49,7 @@ func (s *Server) Router() http.Handler {
|
||||
|
||||
r.Use(middleware.RealIP)
|
||||
r.Use(middleware.Recoverer)
|
||||
r.Use(s.apiLoggingMiddleware)
|
||||
r.Use(cors.Handler(cors.Options{
|
||||
AllowedOrigins: []string{"*"},
|
||||
AllowedMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"},
|
||||
@@ -239,6 +241,54 @@ func writeError(w http.ResponseWriter, status int, message string) {
|
||||
writeJSON(w, status, map[string]string{"error": message})
|
||||
}
|
||||
|
||||
func (s *Server) apiLoggingMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// Only log API requests (/api/...)
|
||||
if !strings.HasPrefix(r.URL.Path, "/api") {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
ww := middleware.NewWrapResponseWriter(w, r.ProtoMajor)
|
||||
|
||||
next.ServeHTTP(ww, r)
|
||||
|
||||
duration := time.Since(start)
|
||||
durationMs := float64(duration.Microseconds()) / 1000.0
|
||||
status := ww.Status()
|
||||
if status == 0 {
|
||||
status = http.StatusOK
|
||||
}
|
||||
|
||||
method := r.Method
|
||||
path := r.URL.Path
|
||||
|
||||
if status >= 500 {
|
||||
slog.Error("HTTP request failed",
|
||||
"method", method,
|
||||
"path", path,
|
||||
"status", status,
|
||||
"duration_ms", durationMs,
|
||||
)
|
||||
} else if status >= 400 {
|
||||
slog.Warn("HTTP request warning",
|
||||
"method", method,
|
||||
"path", path,
|
||||
"status", status,
|
||||
"duration_ms", durationMs,
|
||||
)
|
||||
} else {
|
||||
slog.Debug("HTTP request completed",
|
||||
"method", method,
|
||||
"path", path,
|
||||
"status", status,
|
||||
"duration_ms", durationMs,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Server) authMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// 1. Check Authorization Bearer Token
|
||||
|
||||
Reference in new issue
Block a user