@@ -18,6 +18,7 @@ package x
18
18
19
19
import (
20
20
"errors"
21
+ "io/ioutil"
21
22
"os"
22
23
"strings"
23
24
"time"
@@ -28,8 +29,9 @@ import (
28
29
)
29
30
30
31
var (
31
- env string
32
- dsn string // API KEY to use
32
+ env string
33
+ dsn string // API KEY to use
34
+ cidPath string
33
35
)
34
36
35
37
// Sentry API KEYs to use.
@@ -99,6 +101,41 @@ func ConfigureSentryScope(subcmd string) {
99
101
scope .SetTag ("dgraph" , subcmd )
100
102
scope .SetLevel (sentry .LevelFatal )
101
103
})
104
+
105
+ // e.g. /tmp/dgraph-alpha-cid-sentry
106
+ cidPath = os .TempDir () + "/" + "dgraph-" + subcmd + "-cid-sentry"
107
+ }
108
+
109
+ // WriteCidFile writes the CID to a well-known location so it can be read and
110
+ // sent to Sentry on panic.
111
+ func WriteCidFile (cid string ) {
112
+ if cid == "" {
113
+ return
114
+ }
115
+ if err := ioutil .WriteFile (cidPath , []byte (cid ), 0644 ); err != nil {
116
+ glog .Warningf ("unable to write CID to file %v %v" , cidPath , err )
117
+ return
118
+ }
119
+ }
120
+
121
+ // readAndRemoveCidFile reads the file from a well-known location so
122
+ // it can be read and sent to Sentry on panic.
123
+ func readAndRemoveCidFile () string {
124
+ cid , err := ioutil .ReadFile (cidPath )
125
+ if err != nil {
126
+ glog .Warningf ("unable to read CID from file %v %v. Skip" , cidPath , err )
127
+ return ""
128
+ }
129
+ RemoveCidFile ()
130
+ return string (cid )
131
+ }
132
+
133
+ // RemoveCidFile removes the file.
134
+ func RemoveCidFile () {
135
+ if err := os .RemoveAll (cidPath ); err != nil {
136
+ glog .Warningf ("unable to remove the CID file at %v %v. Skip" , cidPath , err )
137
+ return
138
+ }
102
139
}
103
140
104
141
// CaptureSentryException sends the error report to Sentry.
@@ -111,6 +148,12 @@ func CaptureSentryException(err error) {
111
148
// PanicHandler is the callback function when a panic happens. It does not recover and is
112
149
// only used to log panics (in our case send an event to sentry).
113
150
func PanicHandler (out string ) {
151
+ if cid := readAndRemoveCidFile (); cid != "" {
152
+ // re-configure sentry scope to include cid if found.
153
+ sentry .ConfigureScope (func (scope * sentry.Scope ) {
154
+ scope .SetTag ("CID" , cid )
155
+ })
156
+ }
114
157
// Output contains the full output (including stack traces) of the panic.
115
158
sentry .CaptureException (errors .New (out ))
116
159
FlushSentry () // Need to flush asap. Don't defer here.
@@ -119,7 +162,6 @@ func PanicHandler(out string) {
119
162
}
120
163
121
164
// WrapPanics is a wrapper on panics. We use it to send sentry events about panics
122
- // and crash right after.
123
165
func WrapPanics () {
124
166
exitStatus , err := panicwrap .BasicWrap (PanicHandler )
125
167
if err != nil {
0 commit comments