| package log |
|
|
| import ( |
| "fmt" |
| "log/slog" |
| "os" |
| "runtime/debug" |
| ) |
|
|
| |
| |
| |
| const OTelCodeStackTrace = "code.stacktrace" |
|
|
| type propagationStrategy int8 |
|
|
| const ( |
| |
| propagationStrategyRePanic propagationStrategy = iota |
|
|
| |
| propagationStrategyExit |
|
|
| |
| propagationStrategyContinue |
| ) |
|
|
| type panicLoggerOptions struct { |
| propagationStrategy propagationStrategy |
| } |
|
|
| |
| func WithRePanic(o *panicLoggerOptions) { |
| o.propagationStrategy = propagationStrategyRePanic |
| } |
|
|
| |
| func WithExit(o *panicLoggerOptions) { |
| o.propagationStrategy = propagationStrategyExit |
| } |
|
|
| |
| func WithContinue(o *panicLoggerOptions) { |
| o.propagationStrategy = propagationStrategyContinue |
| } |
|
|
| |
| |
| |
| |
| func PanicLogger(options ...func(*panicLoggerOptions)) { |
| opts := &panicLoggerOptions{} |
|
|
| for _, o := range options { |
| o(opts) |
| } |
|
|
| if r := recover(); r != nil { |
| description := fmt.Sprintf("panic: %s", r) |
|
|
| slog.Error(description, OTelCodeStackTrace, string(debug.Stack())) |
|
|
| switch opts.propagationStrategy { |
| case propagationStrategyExit: |
| os.Exit(1) |
| case propagationStrategyContinue: |
| return |
| case propagationStrategyRePanic: |
| fallthrough |
| default: |
| panic(r) |
| } |
| } |
| } |
|
|