haproxy-lb/pkg/util/crash.go
2021-10-09 16:52:06 +02:00

47 lines
1.2 KiB
Go

package util
import (
"errors"
"fmt"
"net/http"
"runtime"
"github.com/iand/logfmtr"
)
var (
reallyCrash = true
log = logfmtr.New()
panicErr = errors.New("observed a panic")
)
func HandleCrash() {
if r := recover(); r != nil {
logPanic(r)
if reallyCrash {
panic(r)
}
}
}
// logPanic logs the caller tree when a panic occurs (except in the special case of http.ErrAbortHandler).
func logPanic(r interface{}) {
if r == http.ErrAbortHandler {
// honor the http.ErrAbortHandler sentinel panic value:
// ErrAbortHandler is a sentinel panic value to abort a handler.
// While any panic from ServeHTTP aborts the response to the client,
// panicking with ErrAbortHandler also suppresses logging of a stack trace to the server's error log.
return
}
// Same as stdlib http server code. Manually allocate stack trace buffer size
// to prevent excessively large logs
const size = 64 << 10
stacktrace := make([]byte, size)
stacktrace = stacktrace[:runtime.Stack(stacktrace, false)]
if _, ok := r.(string); ok {
log.Error(panicErr, fmt.Sprintf("%s\n%s", r, stacktrace))
} else {
log.Error(panicErr, fmt.Sprintf("%#v (%v)\n%s", r, r, stacktrace))
}
}