Finalize history admin tools and semantic UI navigation

This commit is contained in:
2026-02-23 16:59:09 +03:00
parent 4e8554f5f0
commit 8aa8b26184
43 changed files with 5543 additions and 270 deletions

View File

@@ -4,6 +4,7 @@ import (
"context"
"database/sql"
"encoding/json"
"log"
"net/http"
"time"
@@ -19,6 +20,44 @@ type Server struct {
cancelBg context.CancelFunc
}
type statusCaptureResponseWriter struct {
http.ResponseWriter
status int
}
func (w *statusCaptureResponseWriter) WriteHeader(status int) {
w.status = status
w.ResponseWriter.WriteHeader(status)
}
func (w *statusCaptureResponseWriter) Write(b []byte) (int, error) {
if w.status == 0 {
w.status = http.StatusOK
}
return w.ResponseWriter.Write(b)
}
func withErrorLogging(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
sw := &statusCaptureResponseWriter{ResponseWriter: w}
start := time.Now()
defer func() {
if rec := recover(); rec != nil {
log.Printf("http panic method=%s path=%s remote=%s panic=%v", r.Method, r.URL.Path, r.RemoteAddr, rec)
panic(rec)
}
status := sw.status
if status == 0 {
status = http.StatusOK
}
if status >= 400 {
log.Printf("http response error method=%s path=%s raw_query=%q status=%d remote=%s duration_ms=%d", r.Method, r.URL.Path, r.URL.RawQuery, status, r.RemoteAddr, time.Since(start).Milliseconds())
}
}()
next.ServeHTTP(sw, r)
})
}
func NewServer(addr string, readTimeout, writeTimeout time.Duration, db *sql.DB) *Server {
mux := http.NewServeMux()
mux.HandleFunc("/health", healthHandler)
@@ -68,7 +107,7 @@ func NewServer(addr string, readTimeout, writeTimeout time.Duration, db *sql.DB)
return &Server{
httpServer: &http.Server{
Addr: addr,
Handler: mux,
Handler: withErrorLogging(mux),
ReadTimeout: readTimeout,
WriteTimeout: writeTimeout,
},