// Created on savesnippets.com · https://savesnippets.com/ptL1F58arOOUzp package main import ( "log" "net/http" "time" ) func logging(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() next.ServeHTTP(w, r) log.Printf("%s %s — %s", r.Method, r.URL.Path, time.Since(start)) }) } func recoverer(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { defer func() { if rec := recover(); rec != nil { log.Printf("panic: %v", rec) http.Error(w, "internal error", http.StatusInternalServerError) } }() next.ServeHTTP(w, r) }) } func chain(h http.Handler, ms ...func(http.Handler) http.Handler) http.Handler { for i := len(ms) - 1; i >= 0; i-- { h = ms[i](h) } return h } func main() { mux := http.NewServeMux() mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("hello")) }) handler := chain(mux, logging, recoverer) log.Fatal(http.ListenAndServe(":8080", handler)) }