Add request logging middleware and improve startup diagnostics
- Request logger middleware logs method, path, status, duration for all non-static/health requests (those go to debug level) - Initial fetch complete log now includes repo and doc counts - Helps diagnose deployment and routing issues Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -93,6 +93,7 @@ func New(cfg Config) (*Server, error) {
|
|||||||
// Handler returns the chi router with all routes mounted.
|
// Handler returns the chi router with all routes mounted.
|
||||||
func (s *Server) Handler() http.Handler {
|
func (s *Server) Handler() http.Handler {
|
||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
|
r.Use(s.requestLogger)
|
||||||
|
|
||||||
staticFS, err := fs.Sub(web.Content, "static")
|
staticFS, err := fs.Sub(web.Content, "static")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -327,6 +328,43 @@ func (s *Server) renderError(w http.ResponseWriter, r *http.Request, code int, m
|
|||||||
s.render(w, r, "error.html", data, code)
|
s.render(w, r, "error.html", data, code)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type statusWriter struct {
|
||||||
|
http.ResponseWriter
|
||||||
|
code int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *statusWriter) WriteHeader(code int) {
|
||||||
|
w.code = code
|
||||||
|
w.ResponseWriter.WriteHeader(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) requestLogger(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
start := time.Now()
|
||||||
|
sw := &statusWriter{ResponseWriter: w, code: http.StatusOK}
|
||||||
|
next.ServeHTTP(sw, r)
|
||||||
|
duration := time.Since(start)
|
||||||
|
|
||||||
|
// Skip static assets and health checks at info level
|
||||||
|
if strings.HasPrefix(r.URL.Path, "/static/") || r.URL.Path == "/health" {
|
||||||
|
s.log.Debug("request",
|
||||||
|
"method", r.Method,
|
||||||
|
"path", r.URL.Path,
|
||||||
|
"status", sw.code,
|
||||||
|
"duration", duration,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s.log.Info("request",
|
||||||
|
"method", r.Method,
|
||||||
|
"path", r.URL.Path,
|
||||||
|
"status", sw.code,
|
||||||
|
"duration", duration,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func verifyHMAC(body []byte, signature, secret string) bool {
|
func verifyHMAC(body []byte, signature, secret string) bool {
|
||||||
if signature == "" {
|
if signature == "" {
|
||||||
return false
|
return false
|
||||||
@@ -393,7 +431,12 @@ func StartBackgroundFetch(ctx context.Context, cfg BackgroundConfig) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
cfg.Cache.SetReady()
|
cfg.Cache.SetReady()
|
||||||
log.Info("initial fetch complete")
|
repos := cfg.Cache.ListRepos()
|
||||||
|
totalDocs := 0
|
||||||
|
for _, r := range repos {
|
||||||
|
totalDocs += len(r.Docs)
|
||||||
|
}
|
||||||
|
log.Info("initial fetch complete", "repos", len(repos), "docs", totalDocs)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user