package server import ( "log/slog" "net/http" "time" "github.com/indifferentketchup/llama-sidecar/internal/config" "github.com/indifferentketchup/llama-sidecar/internal/pool" ) func New(cfg *config.Config, p *pool.Pool, startedAt time.Time) *http.Server { mux := http.NewServeMux() mux.HandleFunc("GET /health", healthHandler(p, cfg, startedAt)) mux.HandleFunc("GET /sidecars", listSidecarsHandler(p)) mux.HandleFunc("DELETE /sidecars/{hash}", deleteSidecarHandler(p)) mux.HandleFunc("POST /v1/chat/completions", proxyHandler(p)) mux.HandleFunc("POST /v1/completions", proxyHandler(p)) handler := requestLogger(mux) return &http.Server{ Addr: cfg.Bind, Handler: handler, } } func requestLogger(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() rw := &statusRecorder{ResponseWriter: w, status: 200} next.ServeHTTP(rw, r) slog.Info("request", "method", r.Method, "path", r.URL.Path, "status", rw.status, "duration_ms", time.Since(start).Milliseconds(), ) }) } type statusRecorder struct { http.ResponseWriter status int } func (sr *statusRecorder) WriteHeader(code int) { sr.status = code sr.ResponseWriter.WriteHeader(code) } func (sr *statusRecorder) Flush() { if f, ok := sr.ResponseWriter.(http.Flusher); ok { f.Flush() } }