-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdeferlog.go
62 lines (50 loc) · 1.54 KB
/
deferlog.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package tracing
import (
"context"
"fmt"
"os"
"runtime/debug"
"github.com/getsentry/sentry-go"
log "github.com/sirupsen/logrus"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
)
// LogRecoverToReturn Recovers from a panic, logs and forwards it sentry and otel, then returns
// Does nothing when there is no panic.
func LogRecoverToReturn(ctx context.Context, loc string) {
err := recover()
if err == nil {
return
}
stack := string(debug.Stack())
HandleError(ctx, loc, err, stack)
}
// LogRecoverToExit Recovers from a panic, logs and forwards it sentry and otel, then exits
// Does nothing when there is no panic.
func LogRecoverToExit(ctx context.Context, loc string) {
err := recover()
if err == nil {
return
}
stack := string(debug.Stack())
HandleError(ctx, loc, err, stack)
// ensure that errors still get sent out
ShutdownTracer(ctx)
os.Exit(1)
}
func HandleError(ctx context.Context, loc string, err interface{}, stack string) {
msg := fmt.Sprintf("unhandled panic in %v, exiting: %v", loc, err)
hub := sentry.CurrentHub()
if hub != nil {
hub.Recover(err)
}
// always log to stderr (no WithContext!)
log.WithFields(log.Fields{"loc": loc, "stack": stack}).Error(msg)
// if we have a context, try attaching additional info to the span
if ctx != nil {
log.WithContext(ctx).WithFields(log.Fields{"loc": loc, "stack": stack}).Error(msg)
span := trace.SpanFromContext(ctx)
span.SetAttributes(attribute.String("ovm.panic.loc", loc))
span.SetAttributes(attribute.String("ovm.panic.stack", stack))
}
}