Repository navigation
Expand file tree
/
Copy pathsentry.go
More file actions
188 lines (170 loc) · 6.34 KB
/
Copy pathsentry.go
File metadata and controls
188 lines (170 loc) · 6.34 KB
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
package sentry
import (
"context"
"time"
"github.com/getsentry/sentry-go/internal/debuglog"
)
// The version of the SDK.
const SDKVersion = "1.0.0-alpha.1"
// DefaultFlushTimeout is the default timeout used for flushing events.
const DefaultFlushTimeout = 2 * time.Second
// Init initializes the SDK with options. The returned error is non-nil if
// options is invalid, for instance if a malformed DSN is provided.
func Init(options ClientOptions) error {
client, err := NewClient(options)
if err != nil {
return err
}
setGlobalClient(client)
return nil
}
// AddBreadcrumb records a new breadcrumb using the scope and client carried
// by ctx. The breadcrumb is dropped when ctx carries no scope.
//
// The total number of breadcrumbs that can be recorded are limited by the
// configuration on the client.
func AddBreadcrumb(ctx context.Context, breadcrumb *Breadcrumb, options ...BreadcrumbOption) {
scope := ScopeFromContext(ctx)
if scope == nil {
debuglog.Println("breadcrumb dropped: ctx carries no scope. Use WithScope to start one.")
return
}
client := ClientFromContext(ctx)
limit := client.options.MaxBreadcrumbs
switch {
case limit < 0:
return
case limit == 0:
limit = defaultMaxBreadcrumbs
}
if client.options.BeforeBreadcrumb != nil {
resolved := breadcrumbOptions{}
for _, option := range options {
if option != nil {
option(&resolved)
}
}
if resolved.hint == nil {
resolved.hint = &BreadcrumbHint{}
}
if breadcrumb = client.options.BeforeBreadcrumb(breadcrumb, resolved.hint); breadcrumb == nil {
debuglog.Println("breadcrumb dropped due to BeforeBreadcrumb callback.")
return
}
}
scope.AddBreadcrumb(breadcrumb, limit)
}
// CaptureMessage captures an arbitrary message using the scope and client
// carried by ctx.
func CaptureMessage(ctx context.Context, message string, options ...CaptureOption) *EventID {
return ClientFromContext(ctx).CaptureMessage(ctx, message, options...)
}
// CaptureException captures an error using the scope and client carried by
// ctx.
func CaptureException(ctx context.Context, exception error, options ...CaptureOption) *EventID {
return ClientFromContext(ctx).CaptureException(ctx, exception, options...)
}
// CaptureCheckIn captures a (cron) monitor check-in using the scope and client
// carried by ctx.
func CaptureCheckIn(
ctx context.Context,
checkIn *CheckIn,
monitorConfig *MonitorConfig,
options ...CaptureOption,
) *EventID {
return ClientFromContext(ctx).CaptureCheckIn(ctx, checkIn, monitorConfig, options...)
}
// WithMonitor runs fn and reports its outcome as check-ins for the cron
// monitor identified by monitorSlug, using the scope and client carried by ctx.
//
// An in_progress check-in carrying monitorConfig is sent before fn runs. When
// monitorConfig is not nil, Sentry creates the monitor if it does not exist,
// or updates its configuration. After fn returns, an ok check-in is sent if
// it returned nil, or an error check-in otherwise, along with the measured
// duration. If fn panics, an error check-in is sent and the panic continues.
//
// The error returned by fn is returned unchanged.
func WithMonitor(ctx context.Context, monitorSlug string, monitorConfig *MonitorConfig, fn func() error) error {
ctx, _ = WithScope(ctx)
checkInID := CaptureCheckIn(ctx, &CheckIn{
MonitorSlug: monitorSlug,
Status: CheckInStatusInProgress,
}, monitorConfig)
start := time.Now()
status := CheckInStatusError
defer func() {
checkIn := &CheckIn{
MonitorSlug: monitorSlug,
Status: status,
Duration: time.Since(start),
}
if checkInID != nil {
checkIn.ID = *checkInID
}
CaptureCheckIn(ctx, checkIn, nil)
}()
err := fn()
if err == nil {
status = CheckInStatusOK
}
return err
}
// CaptureEvent captures an event using the scope and client carried by ctx.
//
// The event must already be assembled. Typically code would instead use
// the utility methods like CaptureException. The return value is the
// event ID. In case Sentry is disabled or event was dropped, the return value will be nil.
func CaptureEvent(ctx context.Context, event *Event, options ...CaptureOption) *EventID {
return ClientFromContext(ctx).CaptureEvent(ctx, event, options...)
}
// Recover captures a recovered panic value using the scope and client carried
// by ctx. When recovered is nil, Recover invokes Go's built-in recover and must
// itself be deferred.
func Recover(ctx context.Context, recovered any, options ...CaptureOption) *EventID {
if recovered == nil {
recovered = recover()
}
if recovered == nil {
return nil
}
return ClientFromContext(ctx).capturePanic(ctx, recovered, options...)
}
// Flush waits until the underlying Transport sends any buffered events to the
// Sentry server, blocking for at most the given timeout. It returns false if
// capture is disabled or the timeout was reached. In the latter case, some
// events may not have been sent.
//
// Flush should be called before terminating the program to avoid
// unintentionally dropping events.
//
// Do not call Flush indiscriminately after every call to CaptureEvent,
// CaptureException or CaptureMessage. Instead, to have the SDK send events over
// the network synchronously, configure it to use the HTTPSyncTransport in the
// call to Init.
func Flush(timeout time.Duration) bool {
return ClientFromContext(context.Background()).Flush(timeout)
}
// FlushWithContext waits until the underlying Transport sends any buffered events
// to the Sentry server, blocking for at most the duration specified by the
// context. It returns false if capture is disabled or the context is canceled
// before the events are sent. In the latter case, some events may not be
// delivered.
//
// FlushWithContext should be called before terminating the program to ensure no
// events are unintentionally dropped.
//
// Avoid calling FlushWithContext indiscriminately after each call to CaptureEvent,
// CaptureException, or CaptureMessage. To send events synchronously over the network,
// configure the SDK to use HTTPSyncTransport during initialization with Init.
func FlushWithContext(ctx context.Context) bool {
return ClientFromContext(ctx).FlushWithContext(ctx)
}
// LastEventID returns the last event ID captured in ctx's scope, or an empty
// ID when ctx does not carry one.
func LastEventID(ctx context.Context) EventID {
scope := ScopeFromContext(ctx)
if scope == nil {
return ""
}
return scope.lastEventIDSnapshot()
}