forked from whyrusleeping/distribution
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bugsnag.go
131 lines (113 loc) · 4.45 KB
/
bugsnag.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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package bugsnag
import (
"github.com/bugsnag/bugsnag-go/errors"
"log"
"net/http"
"os"
"sync"
// Fixes a bug with SHA-384 intermediate certs on some platforms.
// - https://github.com/bugsnag/bugsnag-go/issues/9
_ "crypto/sha512"
)
// The current version of bugsnag-go.
const VERSION = "1.0.2"
var once sync.Once
var middleware middlewareStack
// The configuration for the default bugsnag notifier.
var Config Configuration
var defaultNotifier = Notifier{&Config, nil}
// Configure Bugsnag. The only required setting is the APIKey, which can be
// obtained by clicking on "Settings" in your Bugsnag dashboard. This function
// is also responsible for installing the global panic handler, so it should be
// called as early as possible in your initialization process.
func Configure(config Configuration) {
Config.update(&config)
once.Do(Config.PanicHandler)
}
// Notify sends an error to Bugsnag along with the current stack trace. The
// rawData is used to send extra information along with the error. For example
// you can pass the current http.Request to Bugsnag to see information about it
// in the dashboard, or set the severity of the notification.
func Notify(err error, rawData ...interface{}) error {
return defaultNotifier.Notify(errors.New(err, 1), rawData...)
}
// AutoNotify logs a panic on a goroutine and then repanics.
// It should only be used in places that have existing panic handlers further
// up the stack. See bugsnag.Recover(). The rawData is used to send extra
// information along with any panics that are handled this way.
// Usage: defer bugsnag.AutoNotify()
func AutoNotify(rawData ...interface{}) {
if err := recover(); err != nil {
rawData = defaultNotifier.addDefaultSeverity(rawData, SeverityError)
defaultNotifier.Notify(errors.New(err, 2), rawData...)
panic(err)
}
}
// Recover logs a panic on a goroutine and then recovers.
// The rawData is used to send extra information along with
// any panics that are handled this way
// Usage: defer bugsnag.Recover()
func Recover(rawData ...interface{}) {
if err := recover(); err != nil {
rawData = defaultNotifier.addDefaultSeverity(rawData, SeverityWarning)
defaultNotifier.Notify(errors.New(err, 2), rawData...)
}
}
// OnBeforeNotify adds a callback to be run before a notification is sent to
// Bugsnag. It can be used to modify the event or its MetaData. Changes made
// to the configuration are local to notifying about this event. To prevent the
// event from being sent to Bugsnag return an error, this error will be
// returned from bugsnag.Notify() and the event will not be sent.
func OnBeforeNotify(callback func(event *Event, config *Configuration) error) {
middleware.OnBeforeNotify(callback)
}
// Handler creates an http Handler that notifies Bugsnag any panics that
// happen. It then repanics so that the default http Server panic handler can
// handle the panic too. The rawData is used to send extra information along
// with any panics that are handled this way.
func Handler(h http.Handler, rawData ...interface{}) http.Handler {
notifier := New(rawData...)
if h == nil {
h = http.DefaultServeMux
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer notifier.AutoNotify(r)
h.ServeHTTP(w, r)
})
}
// HandlerFunc creates an http HandlerFunc that notifies Bugsnag about any
// panics that happen. It then repanics so that the default http Server panic
// handler can handle the panic too. The rawData is used to send extra
// information along with any panics that are handled this way. If you have
// already wrapped your http server using bugsnag.Handler() you don't also need
// to wrap each HandlerFunc.
func HandlerFunc(h http.HandlerFunc, rawData ...interface{}) http.HandlerFunc {
notifier := New(rawData...)
return func(w http.ResponseWriter, r *http.Request) {
defer notifier.AutoNotify(r)
h(w, r)
}
}
func init() {
// Set up builtin middlewarez
OnBeforeNotify(httpRequestMiddleware)
// Default configuration
Config.update(&Configuration{
APIKey: "",
Endpoint: "https://notify.bugsnag.com/",
Hostname: "",
AppVersion: "",
ReleaseStage: "",
ParamsFilters: []string{"password", "secret"},
// * for app-engine
ProjectPackages: []string{"main*"},
NotifyReleaseStages: nil,
Logger: log.New(os.Stdout, log.Prefix(), log.Flags()),
PanicHandler: defaultPanicHandler,
Transport: http.DefaultTransport,
})
hostname, err := os.Hostname()
if err == nil {
Config.Hostname = hostname
}
}