если вы делаете все руками через net/http, то можно ловить panic (ну или error), и логировать с нужной инфой:
package main
import (
"fmt"
"log"
"net/http"
)
func handle(w http.ResponseWriter, r *http.Request) {
defer func() {
if s := recover(); s != nil {
log.Printf("Recover in %s\n", s)
log.Printf("Request: %s\n", fmt.Sprintf("%+v", r))
http.Error(w, "Sorry, something wrong. Try later", 500)
}
}()
// тут делаем какую-то вещь, которая крашит горутину (допустим, валится вызов библиотечной функции)
// для примера сделаем так:
someCondition := true
if someCondition {
panic("Root")
}
w.Write([]byte("Hello"))
}
func main() {
http.Handle("/", http.HandlerFunc(handle))
http.ListenAndServe(":8080", nil)
}
ну а если будете использовать какой-нибудь фреймворк, то смотрите в его документацию; допустим в beego есть свой логгер, с уровнями и всем прочим