MM-27613: Update dependencies (#15294)
https://mattermost.atlassian.net/browse/MM-27613
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
54f86e7fb1
Коммит
f2a8e10216
10
vendor/github.com/getsentry/sentry-go/.golangci.yml
сгенерированный
поставляемый
10
vendor/github.com/getsentry/sentry-go/.golangci.yml
сгенерированный
поставляемый
@@ -7,11 +7,11 @@ linters:
|
||||
- dogsled
|
||||
- dupl
|
||||
- errcheck
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- goconst
|
||||
- gocritic
|
||||
- gocyclo
|
||||
- godot
|
||||
- gofmt
|
||||
- goimports
|
||||
- golint
|
||||
@@ -33,14 +33,8 @@ linters:
|
||||
- unparam
|
||||
- unused
|
||||
- varcheck
|
||||
run:
|
||||
skip-dirs:
|
||||
- echo
|
||||
- example/echo
|
||||
- whitespace
|
||||
issues:
|
||||
exclude:
|
||||
- "not declared by package utf8"
|
||||
- "unicode/utf8/utf8.go"
|
||||
exclude-rules:
|
||||
- path: _test\.go
|
||||
linters:
|
||||
|
||||
3
vendor/github.com/getsentry/sentry-go/.travis.yml
сгенерированный
поставляемый
3
vendor/github.com/getsentry/sentry-go/.travis.yml
сгенерированный
поставляемый
@@ -24,10 +24,11 @@ jobs:
|
||||
go test ./... -race
|
||||
allow_failures:
|
||||
- go: master
|
||||
- env: GO111MODULE=off
|
||||
fast_finish: true
|
||||
|
||||
before_install:
|
||||
- curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/v1.19.1/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.19.1
|
||||
- curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/v1.27.0/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.27.0
|
||||
# Fetch origin/master. This is required for `git merge-base` when testing a
|
||||
# branch, since Travis clones only the target branch.
|
||||
- git fetch origin master:remotes/origin/master
|
||||
|
||||
28
vendor/github.com/getsentry/sentry-go/CHANGELOG.md
сгенерированный
поставляемый
28
vendor/github.com/getsentry/sentry-go/CHANGELOG.md
сгенерированный
поставляемый
@@ -1,8 +1,32 @@
|
||||
# Changelog
|
||||
|
||||
## Unreleased
|
||||
## v0.7.0
|
||||
|
||||
- "I am running away from my responsibilities. And it feels good." – Michael Scott, Season 4, "Money"
|
||||
- feat: Include original error when event cannot be encoded as JSON (#258)
|
||||
- feat: Use Hub from request context when available (#217, #259)
|
||||
- feat: Extract stack frames from golang.org/x/xerrors (#262)
|
||||
- feat: Make Environment Integration preserve existing context data (#261)
|
||||
- feat: Recover and RecoverWithContext with arbitrary types (#268)
|
||||
- feat: Report bad usage of CaptureMessage and CaptureEvent (#269)
|
||||
- feat: Send debug logging to stderr by default (#266)
|
||||
- feat: Several improvements to documentation (#223, #245, #250, #265)
|
||||
- feat: Example of Recover followed by panic (#241, #247)
|
||||
- feat: Add Transactions and Spans (to support OpenTelemetry Sentry Exporter) (#235, #243, #254)
|
||||
- fix: Set either Frame.Filename or Frame.AbsPath (#233)
|
||||
- fix: Clone requestBody to new Scope (#244)
|
||||
- fix: Synchronize access and mutation of Hub.lastEventID (#264)
|
||||
- fix: Avoid repeated syscalls in prepareEvent (#256)
|
||||
- fix: Do not allocate new RNG for every event (#256)
|
||||
- fix: Remove stale replace directive in go.mod (#255)
|
||||
- fix(http): Deprecate HandleFunc, remove duplication (#260)
|
||||
|
||||
_NOTE:_
|
||||
This version comes packed with several fixes and improvements and no breaking
|
||||
changes.
|
||||
Notably, there is a change in how the SDK reports file names in stack traces
|
||||
that should resolve any ambiguity when looking at stack traces and using the
|
||||
Suspect Commits feature.
|
||||
We recommend all users to upgrade.
|
||||
|
||||
## v0.6.1
|
||||
|
||||
|
||||
59
vendor/github.com/getsentry/sentry-go/CONTRIBUTING.md
сгенерированный
поставляемый
59
vendor/github.com/getsentry/sentry-go/CONTRIBUTING.md
сгенерированный
поставляемый
@@ -1,3 +1,45 @@
|
||||
# Contributing to sentry-go
|
||||
|
||||
Hey, thank you if you're reading this, we welcome your contribution!
|
||||
|
||||
## Sending a Pull Request
|
||||
|
||||
Please help us save time when reviewing your PR by following this simple
|
||||
process:
|
||||
|
||||
1. Is your PR a simple typo fix? Read no further, **click that green "Create
|
||||
pull request" button**!
|
||||
|
||||
2. For more complex PRs that involve behavior changes or new APIs, please
|
||||
consider [opening an **issue**][new-issue] describing the problem you're
|
||||
trying to solve if there's not one already.
|
||||
|
||||
A PR is often one specific solution to a problem and sometimes talking about
|
||||
the problem unfolds new possible solutions. Remember we will be responsible
|
||||
for maintaining the changes later.
|
||||
|
||||
3. Fixing a bug and changing a behavior? Please add automated tests to prevent
|
||||
future regression.
|
||||
|
||||
4. Practice writing good commit messages. We have [commit
|
||||
guidelines][commit-guide].
|
||||
|
||||
5. We have [guidelines for PR submitters][pr-guide]. A short summary:
|
||||
|
||||
- Good PR descriptions are very helpful and most of the time they include
|
||||
**why** something is done and why done in this particular way. Also list
|
||||
other possible solutions that were considered and discarded.
|
||||
- Be your own first reviewer. Make sure your code compiles and passes the
|
||||
existing tests.
|
||||
|
||||
[new-issue]: https://github.com/getsentry/sentry-go/issues/new/choose
|
||||
[commit-guide]: https://develop.sentry.dev/code-review/#commit-guidelines
|
||||
[pr-guide]: https://develop.sentry.dev/code-review/#guidelines-for-submitters
|
||||
|
||||
Please also read through our [SDK Development docs](https://develop.sentry.dev/sdk/).
|
||||
It contains information about SDK features, expected payloads and best practices for
|
||||
contributing to Sentry SDKs.
|
||||
|
||||
## Community
|
||||
|
||||
The public-facing channels for support and development of Sentry SDKs can be found on [Discord](https://discord.gg/Ww9hbqr).
|
||||
@@ -23,6 +65,7 @@ $ go test -race
|
||||
```
|
||||
|
||||
### Coverage
|
||||
|
||||
```console
|
||||
$ go test -race -coverprofile=coverage.txt -covermode=atomic && go tool cover -html coverage.txt
|
||||
```
|
||||
@@ -37,17 +80,17 @@ $ golangci-lint run
|
||||
|
||||
1. Update `CHANGELOG.md` with new version in `vX.X.X` format title and list of changes.
|
||||
|
||||
The command below can be used to get a list of changes since the last tag, with the format used in `CHANGELOG.md`:
|
||||
The command below can be used to get a list of changes since the last tag, with the format used in `CHANGELOG.md`:
|
||||
|
||||
```console
|
||||
$ git log --no-merges --format=%s $(git describe --abbrev=0).. | sed 's/^/- /'
|
||||
```
|
||||
```console
|
||||
$ git log --no-merges --format=%s $(git describe --abbrev=0).. | sed 's/^/- /'
|
||||
```
|
||||
|
||||
2. Commit with `misc: vX.X.X changelog` commit message and push to `master`.
|
||||
|
||||
3. Let [`craft`](https://github.com/getsentry/craft) do the rest:
|
||||
|
||||
```console
|
||||
$ craft prepare X.X.X
|
||||
$ craft publish X.X.X
|
||||
```
|
||||
```console
|
||||
$ craft prepare X.X.X
|
||||
$ craft publish X.X.X
|
||||
```
|
||||
|
||||
2
vendor/github.com/getsentry/sentry-go/README.md
сгенерированный
поставляемый
2
vendor/github.com/getsentry/sentry-go/README.md
сгенерированный
поставляемый
@@ -154,7 +154,7 @@ checkout the official documentation:
|
||||
|
||||
- [Configuration](https://docs.sentry.io/platforms/go/config)
|
||||
- [Error Reporting](https://docs.sentry.io/error-reporting/quickstart?platform=go)
|
||||
- [Enriching Error Data](https://docs.sentry.io/enriching-error-data/context?platform=go)
|
||||
- [Enriching Error Data](https://docs.sentry.io/enriching-error-data/additional-data/?platform=go)
|
||||
- [Transports](https://docs.sentry.io/platforms/go/transports)
|
||||
- [Integrations](https://docs.sentry.io/platforms/go/integrations)
|
||||
- [net/http](https://docs.sentry.io/platforms/go/http)
|
||||
|
||||
175
vendor/github.com/getsentry/sentry-go/client.go
сгенерированный
поставляемый
175
vendor/github.com/getsentry/sentry-go/client.go
сгенерированный
поставляемый
@@ -12,6 +12,7 @@ import (
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -24,6 +25,40 @@ import (
|
||||
// stack trace is often the most useful information.
|
||||
const maxErrorDepth = 10
|
||||
|
||||
// hostname is the host name reported by the kernel. It is precomputed once to
|
||||
// avoid syscalls when capturing events.
|
||||
//
|
||||
// The error is ignored because retrieving the host name is best-effort. If the
|
||||
// error is non-nil, there is nothing to do other than retrying. We choose not
|
||||
// to retry for now.
|
||||
var hostname, _ = os.Hostname()
|
||||
|
||||
// lockedRand is a random number generator safe for concurrent use. Its API is
|
||||
// intentionally limited and it is not meant as a full replacement for a
|
||||
// rand.Rand.
|
||||
type lockedRand struct {
|
||||
mu sync.Mutex
|
||||
r *rand.Rand
|
||||
}
|
||||
|
||||
// Float64 returns a pseudo-random number in [0.0,1.0).
|
||||
func (r *lockedRand) Float64() float64 {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
return r.r.Float64()
|
||||
}
|
||||
|
||||
// rng is the internal random number generator.
|
||||
//
|
||||
// We do not use the global functions from math/rand because, while they are
|
||||
// safe for concurrent use, any package in a build could change the seed and
|
||||
// affect the generated numbers, for instance making them deterministic. On the
|
||||
// other hand, the source returned from rand.NewSource is not safe for
|
||||
// concurrent use, so we need to couple its use with a sync.Mutex.
|
||||
var rng = &lockedRand{
|
||||
r: rand.New(rand.NewSource(time.Now().UnixNano())),
|
||||
}
|
||||
|
||||
// usageError is used to report to Sentry an SDK usage error.
|
||||
//
|
||||
// It is not exported because it is never returned by any function or method in
|
||||
@@ -33,17 +68,27 @@ type usageError struct {
|
||||
}
|
||||
|
||||
// Logger is an instance of log.Logger that is use to provide debug information about running Sentry Client
|
||||
// can be enabled by either using `Logger.SetOutput` directly or with `Debug` client option
|
||||
var Logger = log.New(ioutil.Discard, "[Sentry] ", log.LstdFlags) //nolint: gochecknoglobals
|
||||
// can be enabled by either using Logger.SetOutput directly or with Debug client option.
|
||||
var Logger = log.New(ioutil.Discard, "[Sentry] ", log.LstdFlags)
|
||||
|
||||
// EventProcessor is a function that processes an event.
|
||||
// Event processors are used to change an event before it is sent to Sentry.
|
||||
type EventProcessor func(event *Event, hint *EventHint) *Event
|
||||
|
||||
// EventModifier is the interface that wraps the ApplyToEvent method.
|
||||
//
|
||||
// ApplyToEvent changes an event based on external data and/or
|
||||
// an event hint.
|
||||
type EventModifier interface {
|
||||
ApplyToEvent(event *Event, hint *EventHint) *Event
|
||||
}
|
||||
|
||||
var globalEventProcessors []EventProcessor //nolint: gochecknoglobals
|
||||
var globalEventProcessors []EventProcessor
|
||||
|
||||
// AddGlobalEventProcessor adds processor to the global list of event
|
||||
// processors. Global event processors apply to all events.
|
||||
//
|
||||
// Deprecated: Use Scope.AddEventProcessor or Client.AddEventProcessor instead.
|
||||
func AddGlobalEventProcessor(processor EventProcessor) {
|
||||
globalEventProcessors = append(globalEventProcessors, processor)
|
||||
}
|
||||
@@ -54,14 +99,16 @@ type Integration interface {
|
||||
SetupOnce(client *Client)
|
||||
}
|
||||
|
||||
// ClientOptions that configures a SDK Client
|
||||
// ClientOptions that configures a SDK Client.
|
||||
type ClientOptions struct {
|
||||
// The DSN to use. If the DSN is not set, the client is effectively disabled.
|
||||
// The DSN to use. If the DSN is not set, the client is effectively
|
||||
// disabled.
|
||||
Dsn string
|
||||
// In debug mode, the debug information is printed to stdout to help you understand what
|
||||
// sentry is doing.
|
||||
// In debug mode, the debug information is printed to stdout to help you
|
||||
// understand what sentry is doing.
|
||||
Debug bool
|
||||
// Configures whether SDK should generate and attach stacktraces to pure capture message calls.
|
||||
// Configures whether SDK should generate and attach stacktraces to pure
|
||||
// capture message calls.
|
||||
AttachStacktrace bool
|
||||
// The sample rate for event submission (0.0 - 1.0, defaults to 1.0).
|
||||
SampleRate float64
|
||||
@@ -73,13 +120,12 @@ type ClientOptions struct {
|
||||
BeforeSend func(event *Event, hint *EventHint) *Event
|
||||
// Before breadcrumb add callback.
|
||||
BeforeBreadcrumb func(breadcrumb *Breadcrumb, hint *BreadcrumbHint) *Breadcrumb
|
||||
// Integrations to be installed on the current Client, receives default integrations
|
||||
// Integrations to be installed on the current Client, receives default
|
||||
// integrations.
|
||||
Integrations func([]Integration) []Integration
|
||||
// io.Writer implementation that should be used with the `Debug` mode
|
||||
// io.Writer implementation that should be used with the Debug mode.
|
||||
DebugWriter io.Writer
|
||||
// The transport to use.
|
||||
// This is an instance of a struct implementing `Transport` interface.
|
||||
// Defaults to `httpTransport` from `transport.go`
|
||||
// The transport to use. Defaults to HTTPTransport.
|
||||
Transport Transport
|
||||
// The server name to be reported.
|
||||
ServerName string
|
||||
@@ -91,26 +137,27 @@ type ClientOptions struct {
|
||||
Environment string
|
||||
// Maximum number of breadcrumbs.
|
||||
MaxBreadcrumbs int
|
||||
// An optional pointer to `http.Client` that will be used with a default HTTPTransport.
|
||||
// Using your own client will make HTTPTransport, HTTPProxy, HTTPSProxy and CaCerts options ignored.
|
||||
// An optional pointer to http.Client that will be used with a default
|
||||
// HTTPTransport. Using your own client will make HTTPTransport, HTTPProxy,
|
||||
// HTTPSProxy and CaCerts options ignored.
|
||||
HTTPClient *http.Client
|
||||
// An optional pointer to `http.Transport` that will be used with a default HTTPTransport.
|
||||
// Using your own transport will make HTTPProxy, HTTPSProxy and CaCerts options ignored.
|
||||
// An optional pointer to http.Transport that will be used with a default
|
||||
// HTTPTransport. Using your own transport will make HTTPProxy, HTTPSProxy
|
||||
// and CaCerts options ignored.
|
||||
HTTPTransport http.RoundTripper
|
||||
// An optional HTTP proxy to use.
|
||||
// This will default to the `http_proxy` environment variable.
|
||||
// or `https_proxy` if that one exists.
|
||||
// This will default to the HTTP_PROXY environment variable.
|
||||
HTTPProxy string
|
||||
// An optional HTTPS proxy to use.
|
||||
// This will default to the `HTTPS_PROXY` environment variable
|
||||
// or `http_proxy` if that one exists.
|
||||
// This will default to the HTTPS_PROXY environment variable.
|
||||
// HTTPS_PROXY takes precedence over HTTP_PROXY for https requests.
|
||||
HTTPSProxy string
|
||||
// An optional CaCerts to use.
|
||||
// Defaults to `gocertifi.CACerts()`.
|
||||
// An optional set of SSL certificates to use.
|
||||
CaCerts *x509.CertPool
|
||||
}
|
||||
|
||||
// Client is the underlying processor that's used by the main API and `Hub` instances.
|
||||
// Client is the underlying processor that is used by the main API and Hub
|
||||
// instances.
|
||||
type Client struct {
|
||||
options ClientOptions
|
||||
dsn *Dsn
|
||||
@@ -119,12 +166,12 @@ type Client struct {
|
||||
Transport Transport
|
||||
}
|
||||
|
||||
// NewClient creates and returns an instance of `Client` configured using `ClientOptions`.
|
||||
// NewClient creates and returns an instance of Client configured using ClientOptions.
|
||||
func NewClient(options ClientOptions) (*Client, error) {
|
||||
if options.Debug {
|
||||
debugWriter := options.DebugWriter
|
||||
if debugWriter == nil {
|
||||
debugWriter = os.Stdout
|
||||
debugWriter = os.Stderr
|
||||
}
|
||||
Logger.SetOutput(debugWriter)
|
||||
}
|
||||
@@ -204,7 +251,7 @@ func (client *Client) AddEventProcessor(processor EventProcessor) {
|
||||
client.eventProcessors = append(client.eventProcessors, processor)
|
||||
}
|
||||
|
||||
// Options return `ClientOptions` for the current `Client`.
|
||||
// Options return ClientOptions for the current Client.
|
||||
func (client Client) Options() ClientOptions {
|
||||
return client.options
|
||||
}
|
||||
@@ -224,36 +271,29 @@ func (client *Client) CaptureException(exception error, hint *EventHint, scope E
|
||||
// CaptureEvent captures an event on the currently active client if any.
|
||||
//
|
||||
// The event must already be assembled. Typically code would instead use
|
||||
// the utility methods like `CaptureException`. The return value is the
|
||||
// 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 (client *Client) CaptureEvent(event *Event, hint *EventHint, scope EventModifier) *EventID {
|
||||
return client.processEvent(event, hint, scope)
|
||||
}
|
||||
|
||||
// Recover captures a panic.
|
||||
// Returns `EventID` if successfully, or `nil` if there's no error to recover from.
|
||||
// Returns EventID if successfully, or nil if there's no error to recover from.
|
||||
func (client *Client) Recover(err interface{}, hint *EventHint, scope EventModifier) *EventID {
|
||||
if err == nil {
|
||||
err = recover()
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if err, ok := err.(error); ok {
|
||||
event := client.eventFromException(err, LevelFatal)
|
||||
return client.CaptureEvent(event, hint, scope)
|
||||
}
|
||||
|
||||
if err, ok := err.(string); ok {
|
||||
event := client.eventFromMessage(err, LevelFatal)
|
||||
return client.CaptureEvent(event, hint, scope)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
// Normally we would not pass a nil Context, but RecoverWithContext doesn't
|
||||
// use the Context for communicating deadline nor cancelation. All it does
|
||||
// is store the Context in the EventHint and there nil means the Context is
|
||||
// not available.
|
||||
//nolint: staticcheck
|
||||
return client.RecoverWithContext(nil, err, hint, scope)
|
||||
}
|
||||
|
||||
// Recover captures a panic and passes relevant context object.
|
||||
// Returns `EventID` if successfully, or `nil` if there's no error to recover from.
|
||||
// RecoverWithContext captures a panic and passes relevant context object.
|
||||
// Returns EventID if successfully, or nil if there's no error to recover from.
|
||||
func (client *Client) RecoverWithContext(
|
||||
ctx context.Context,
|
||||
err interface{},
|
||||
@@ -263,24 +303,29 @@ func (client *Client) RecoverWithContext(
|
||||
if err == nil {
|
||||
err = recover()
|
||||
}
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if hint.Context == nil && ctx != nil {
|
||||
if ctx != nil {
|
||||
if hint == nil {
|
||||
hint = &EventHint{}
|
||||
}
|
||||
if hint.Context == nil {
|
||||
hint.Context = ctx
|
||||
}
|
||||
|
||||
if err, ok := err.(error); ok {
|
||||
event := client.eventFromException(err, LevelFatal)
|
||||
return client.CaptureEvent(event, hint, scope)
|
||||
}
|
||||
|
||||
if err, ok := err.(string); ok {
|
||||
event := client.eventFromMessage(err, LevelFatal)
|
||||
return client.CaptureEvent(event, hint, scope)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
var event *Event
|
||||
switch err := err.(type) {
|
||||
case error:
|
||||
event = client.eventFromException(err, LevelFatal)
|
||||
case string:
|
||||
event = client.eventFromMessage(err, LevelFatal)
|
||||
default:
|
||||
event = client.eventFromMessage(fmt.Sprintf("%#v", err), LevelFatal)
|
||||
}
|
||||
return client.CaptureEvent(event, hint, scope)
|
||||
}
|
||||
|
||||
// Flush waits until the underlying Transport sends any buffered events to the
|
||||
@@ -299,6 +344,10 @@ func (client *Client) Flush(timeout time.Duration) bool {
|
||||
}
|
||||
|
||||
func (client *Client) eventFromMessage(message string, level Level) *Event {
|
||||
if message == "" {
|
||||
err := usageError{fmt.Errorf("%s called with empty message", callerFunctionName())}
|
||||
return client.eventFromException(err, level)
|
||||
}
|
||||
event := NewEvent()
|
||||
event.Level = level
|
||||
event.Message = message
|
||||
@@ -362,6 +411,11 @@ func reverse(a []Exception) {
|
||||
}
|
||||
|
||||
func (client *Client) processEvent(event *Event, hint *EventHint, scope EventModifier) *EventID {
|
||||
if event == nil {
|
||||
err := usageError{fmt.Errorf("%s called with nil event", callerFunctionName())}
|
||||
return client.CaptureException(err, hint, scope)
|
||||
}
|
||||
|
||||
options := client.Options()
|
||||
|
||||
// TODO: Reconsider if its worth going away from default implementation
|
||||
@@ -369,7 +423,7 @@ func (client *Client) processEvent(event *Event, hint *EventHint, scope EventMod
|
||||
// which means that if someone uses ClientOptions{} struct directly
|
||||
// and we would not check for 0 here, we'd skip all events by default
|
||||
if options.SampleRate != 0.0 {
|
||||
randomFloat := rand.New(rand.NewSource(time.Now().UnixNano())).Float64()
|
||||
randomFloat := rng.Float64()
|
||||
if randomFloat > options.SampleRate {
|
||||
Logger.Println("Event dropped due to SampleRate hit.")
|
||||
return nil
|
||||
@@ -380,7 +434,8 @@ func (client *Client) processEvent(event *Event, hint *EventHint, scope EventMod
|
||||
return nil
|
||||
}
|
||||
|
||||
if options.BeforeSend != nil {
|
||||
// As per spec, transactions do not go through BeforeSend.
|
||||
if event.Type != transactionType && options.BeforeSend != nil {
|
||||
h := &EventHint{}
|
||||
if hint != nil {
|
||||
h = hint
|
||||
@@ -412,7 +467,7 @@ func (client *Client) prepareEvent(event *Event, hint *EventHint, scope EventMod
|
||||
if event.ServerName == "" {
|
||||
if client.Options().ServerName != "" {
|
||||
event.ServerName = client.Options().ServerName
|
||||
} else if hostname, err := os.Hostname(); err == nil {
|
||||
} else {
|
||||
event.ServerName = hostname
|
||||
}
|
||||
}
|
||||
|
||||
38
vendor/github.com/getsentry/sentry-go/doc.go
сгенерированный
поставляемый
Обычный файл
38
vendor/github.com/getsentry/sentry-go/doc.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
Package sentry is the official Sentry SDK for Go.
|
||||
|
||||
For more information about Sentry and SDK features please have a look at the
|
||||
documentation site https://docs.sentry.io/platforms/go/.
|
||||
|
||||
Basic Usage
|
||||
|
||||
The first step is to initialize the SDK, providing at a minimum the DSN of your
|
||||
Sentry project. This step is accomplished through a call to sentry.Init.
|
||||
|
||||
func main() {
|
||||
err := sentry.Init(...)
|
||||
...
|
||||
}
|
||||
|
||||
A more detailed yet simple example is available at
|
||||
https://github.com/getsentry/sentry-go/blob/master/example/basic/main.go.
|
||||
|
||||
Integrations
|
||||
|
||||
The SDK has support for several Go frameworks, available as subpackages.
|
||||
|
||||
Getting Support
|
||||
|
||||
For paid Sentry.io accounts, head out to https://sentry.io/support.
|
||||
|
||||
For all users, support channels include:
|
||||
Forum: https://forum.sentry.io
|
||||
Discord: https://discord.gg/Ww9hbqr (#go channel)
|
||||
|
||||
If you found an issue with the SDK, please report through
|
||||
https://github.com/getsentry/sentry-go/issues/new/choose.
|
||||
|
||||
For responsibly disclosing a security issue, please follow the steps in
|
||||
https://sentry.io/security/#vulnerability-disclosure.
|
||||
*/
|
||||
package sentry
|
||||
24
vendor/github.com/getsentry/sentry-go/dsn.go
сгенерированный
поставляемый
24
vendor/github.com/getsentry/sentry-go/dsn.go
сгенерированный
поставляемый
@@ -27,6 +27,8 @@ func (scheme scheme) defaultPort() int {
|
||||
}
|
||||
}
|
||||
|
||||
// DsnParseError represents an error that occurs if a Sentry
|
||||
// DSN cannot be parsed.
|
||||
type DsnParseError struct {
|
||||
Message string
|
||||
}
|
||||
@@ -46,7 +48,7 @@ type Dsn struct {
|
||||
projectID int
|
||||
}
|
||||
|
||||
// NewDsn creates an instance of `Dsn` by parsing provided url in a `string` format.
|
||||
// NewDsn creates an instance of Dsn by parsing provided url in a string format.
|
||||
// If Dsn is not set the client is effectively disabled.
|
||||
func NewDsn(rawURL string) (*Dsn, error) {
|
||||
// Parse
|
||||
@@ -123,7 +125,7 @@ func NewDsn(rawURL string) (*Dsn, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// String formats Dsn struct into a valid string url
|
||||
// String formats Dsn struct into a valid string url.
|
||||
func (dsn Dsn) String() string {
|
||||
var url string
|
||||
url += fmt.Sprintf("%s://%s", dsn.scheme, dsn.publicKey)
|
||||
@@ -141,9 +143,19 @@ func (dsn Dsn) String() string {
|
||||
return url
|
||||
}
|
||||
|
||||
// StoreAPIURL returns assembled url to be used in the transport.
|
||||
// It points to configures Sentry instance.
|
||||
// StoreAPIURL returns the URL of the store endpoint of the project associated
|
||||
// with the DSN.
|
||||
func (dsn Dsn) StoreAPIURL() *url.URL {
|
||||
return dsn.getAPIURL("store")
|
||||
}
|
||||
|
||||
// EnvelopeAPIURL returns the URL of the envelope endpoint of the project
|
||||
// associated with the DSN.
|
||||
func (dsn Dsn) EnvelopeAPIURL() *url.URL {
|
||||
return dsn.getAPIURL("envelope")
|
||||
}
|
||||
|
||||
func (dsn Dsn) getAPIURL(s string) *url.URL {
|
||||
var rawURL string
|
||||
rawURL += fmt.Sprintf("%s://%s", dsn.scheme, dsn.host)
|
||||
if dsn.port != dsn.scheme.defaultPort() {
|
||||
@@ -152,7 +164,7 @@ func (dsn Dsn) StoreAPIURL() *url.URL {
|
||||
if dsn.path != "" {
|
||||
rawURL += dsn.path
|
||||
}
|
||||
rawURL += fmt.Sprintf("/api/%d/store/", dsn.projectID)
|
||||
rawURL += fmt.Sprintf("/api/%d/%s/", dsn.projectID, s)
|
||||
parsedURL, _ := url.Parse(rawURL)
|
||||
return parsedURL
|
||||
}
|
||||
@@ -172,10 +184,12 @@ func (dsn Dsn) RequestHeaders() map[string]string {
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalJSON converts the Dsn struct to JSON.
|
||||
func (dsn Dsn) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(dsn.String())
|
||||
}
|
||||
|
||||
// UnmarshalJSON converts JSON data to the Dsn struct.
|
||||
func (dsn *Dsn) UnmarshalJSON(data []byte) error {
|
||||
var str string
|
||||
_ = json.Unmarshal(data, &str)
|
||||
|
||||
2
vendor/github.com/getsentry/sentry-go/go.mod
сгенерированный
поставляемый
2
vendor/github.com/getsentry/sentry-go/go.mod
сгенерированный
поставляемый
@@ -31,5 +31,3 @@ require (
|
||||
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
|
||||
github.com/yudai/pp v2.0.1+incompatible // indirect
|
||||
)
|
||||
|
||||
replace github.com/ugorji/go v1.1.4 => github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43
|
||||
|
||||
4
vendor/github.com/getsentry/sentry-go/go.sum
сгенерированный
поставляемый
4
vendor/github.com/getsentry/sentry-go/go.sum
сгенерированный
поставляемый
@@ -170,13 +170,11 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/ugorji/go v1.1.2/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 h1:3SVOIvH7Ae1KRYyQWRjXWJEA9sS/c/pjvH++55Gr648=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43 h1:BasDe+IErOQKrMVXab7UayvSlIpiyGwRvuX3EKYY7UA=
|
||||
github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43/go.mod h1:iT03XoTwV7xq/+UGwKO3UbC1nNNlopQiY61beSdrtOA=
|
||||
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
|
||||
|
||||
34
vendor/github.com/getsentry/sentry-go/http/sentryhttp.go
сгенерированный
поставляемый
34
vendor/github.com/getsentry/sentry-go/http/sentryhttp.go
сгенерированный
поставляемый
@@ -50,32 +50,28 @@ func New(options Options) *Handler {
|
||||
|
||||
// Handle wraps http.Handler and recovers from caught panics.
|
||||
func (h *Handler) Handle(handler http.Handler) http.Handler {
|
||||
return h.handle(handler)
|
||||
}
|
||||
|
||||
// Deprecated: Use the Handle method instead.
|
||||
func (h *Handler) HandleFunc(handler http.HandlerFunc) http.HandlerFunc {
|
||||
return h.handle(handler)
|
||||
}
|
||||
|
||||
func (h *Handler) handle(handler http.Handler) http.HandlerFunc {
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
hub := sentry.CurrentHub().Clone()
|
||||
ctx := r.Context()
|
||||
hub := sentry.GetHubFromContext(ctx)
|
||||
if hub == nil {
|
||||
hub = sentry.CurrentHub().Clone()
|
||||
}
|
||||
hub.Scope().SetRequest(r)
|
||||
ctx := sentry.SetHubOnContext(
|
||||
r.Context(),
|
||||
hub,
|
||||
)
|
||||
ctx = sentry.SetHubOnContext(ctx, hub)
|
||||
defer h.recoverWithSentry(hub, r)
|
||||
handler.ServeHTTP(rw, r.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
|
||||
// HandleFunc wraps http.HandleFunc and recovers from caught panics.
|
||||
func (h *Handler) HandleFunc(handler http.HandlerFunc) http.HandlerFunc {
|
||||
return func(rw http.ResponseWriter, r *http.Request) {
|
||||
hub := sentry.CurrentHub().Clone()
|
||||
hub.Scope().SetRequest(r)
|
||||
ctx := sentry.SetHubOnContext(
|
||||
r.Context(),
|
||||
hub,
|
||||
)
|
||||
defer h.recoverWithSentry(hub, r)
|
||||
handler(rw, r.WithContext(ctx))
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) recoverWithSentry(hub *sentry.Hub, r *http.Request) {
|
||||
if err := recover(); err != nil {
|
||||
eventID := hub.RecoverWithContext(
|
||||
|
||||
115
vendor/github.com/getsentry/sentry-go/hub.go
сгенерированный
поставляемый
115
vendor/github.com/getsentry/sentry-go/hub.go
сгенерированный
поставляемый
@@ -8,21 +8,25 @@ import (
|
||||
|
||||
type contextKey int
|
||||
|
||||
// HubContextKey is a context key used to store Hub on any context.Context type
|
||||
const HubContextKey = contextKey(1)
|
||||
// Keys used to store values in a Context. Use with Context.Value to access
|
||||
// values stored by the SDK.
|
||||
const (
|
||||
// HubContextKey is the key used to store the current Hub.
|
||||
HubContextKey = contextKey(1)
|
||||
// RequestContextKey is the key used to store the current http.Request.
|
||||
RequestContextKey = contextKey(2)
|
||||
)
|
||||
|
||||
// RequestContextKey is a context key used to store http.Request on the context passed to RecoverWithContext
|
||||
const RequestContextKey = contextKey(2)
|
||||
|
||||
// Default maximum number of breadcrumbs added to an event. Can be overwritten `maxBreadcrumbs` option.
|
||||
// defaultMaxBreadcrumbs is the default maximum number of breadcrumbs added to
|
||||
// an event. Can be overwritten with the maxBreadcrumbs option.
|
||||
const defaultMaxBreadcrumbs = 30
|
||||
|
||||
// Absolute maximum number of breadcrumbs added to an event.
|
||||
// The `maxBreadcrumbs` option cannot be higher than this value.
|
||||
// maxBreadcrumbs is the absolute maximum number of breadcrumbs added to an
|
||||
// event. The maxBreadcrumbs option cannot be set higher than this value.
|
||||
const maxBreadcrumbs = 100
|
||||
|
||||
// Initial instance of the Hub that has no `Client` bound and an empty `Scope`
|
||||
var currentHub = NewHub(nil, NewScope()) //nolint: gochecknoglobals
|
||||
// currentHub is the initial Hub with no Client bound and an empty Scope.
|
||||
var currentHub = NewHub(nil, NewScope())
|
||||
|
||||
// Hub is the central object that manages scopes and clients.
|
||||
//
|
||||
@@ -31,7 +35,7 @@ var currentHub = NewHub(nil, NewScope()) //nolint: gochecknoglobals
|
||||
//
|
||||
// In most situations developers do not need to interface the hub. Instead
|
||||
// toplevel convenience functions are exposed that will automatically dispatch
|
||||
// to global (`CurrentHub`) hub. In some situations this might not be
|
||||
// to global (CurrentHub) hub. In some situations this might not be
|
||||
// possible in which case it might become necessary to manually work with the
|
||||
// hub. This is for instance the case when working with async code.
|
||||
type Hub struct {
|
||||
@@ -64,7 +68,7 @@ func (l *layer) SetClient(c *Client) {
|
||||
|
||||
type stack []*layer
|
||||
|
||||
// NewHub returns an instance of a `Hub` with provided `Client` and `Scope` bound.
|
||||
// NewHub returns an instance of a Hub with provided Client and Scope bound.
|
||||
func NewHub(client *Client, scope *Scope) *Hub {
|
||||
hub := Hub{
|
||||
stack: &stack{{
|
||||
@@ -75,13 +79,16 @@ func NewHub(client *Client, scope *Scope) *Hub {
|
||||
return &hub
|
||||
}
|
||||
|
||||
// CurrentHub returns an instance of previously initialized `Hub` stored in the global namespace.
|
||||
// CurrentHub returns an instance of previously initialized Hub stored in the global namespace.
|
||||
func CurrentHub() *Hub {
|
||||
return currentHub
|
||||
}
|
||||
|
||||
// LastEventID returns an ID of last captured event for the current `Hub`.
|
||||
// LastEventID returns an ID of last captured event for the current Hub.
|
||||
func (hub *Hub) LastEventID() EventID {
|
||||
hub.mu.RLock()
|
||||
defer hub.mu.RUnlock()
|
||||
|
||||
return hub.lastEventID
|
||||
}
|
||||
|
||||
@@ -116,7 +123,7 @@ func (hub *Hub) Clone() *Hub {
|
||||
return NewHub(top.Client(), scope)
|
||||
}
|
||||
|
||||
// Scope returns top-level `Scope` of the current `Hub` or `nil` if no `Scope` is bound.
|
||||
// Scope returns top-level Scope of the current Hub or nil if no Scope is bound.
|
||||
func (hub *Hub) Scope() *Scope {
|
||||
top := hub.stackTop()
|
||||
if top == nil {
|
||||
@@ -125,7 +132,7 @@ func (hub *Hub) Scope() *Scope {
|
||||
return top.scope
|
||||
}
|
||||
|
||||
// Scope returns top-level `Client` of the current `Hub` or `nil` if no `Client` is bound.
|
||||
// Client returns top-level Client of the current Hub or nil if no Client is bound.
|
||||
func (hub *Hub) Client() *Client {
|
||||
top := hub.stackTop()
|
||||
if top == nil {
|
||||
@@ -134,7 +141,7 @@ func (hub *Hub) Client() *Client {
|
||||
return top.Client()
|
||||
}
|
||||
|
||||
// PushScope pushes a new scope for the current `Hub` and reuses previously bound `Client`.
|
||||
// PushScope pushes a new scope for the current Hub and reuses previously bound Client.
|
||||
func (hub *Hub) PushScope() *Scope {
|
||||
top := hub.stackTop()
|
||||
|
||||
@@ -161,7 +168,7 @@ func (hub *Hub) PushScope() *Scope {
|
||||
return scope
|
||||
}
|
||||
|
||||
// PushScope pops the most recent scope for the current `Hub`.
|
||||
// PopScope pops the most recent scope for the current Hub.
|
||||
func (hub *Hub) PopScope() {
|
||||
hub.mu.Lock()
|
||||
defer hub.mu.Unlock()
|
||||
@@ -173,7 +180,7 @@ func (hub *Hub) PopScope() {
|
||||
}
|
||||
}
|
||||
|
||||
// BindClient binds a new `Client` for the current `Hub`.
|
||||
// BindClient binds a new Client for the current Hub.
|
||||
func (hub *Hub) BindClient(client *Client) {
|
||||
top := hub.stackTop()
|
||||
if top != nil {
|
||||
@@ -181,36 +188,46 @@ func (hub *Hub) BindClient(client *Client) {
|
||||
}
|
||||
}
|
||||
|
||||
// WithScope temporarily pushes a scope for a single call.
|
||||
// WithScope runs f in an isolated temporary scope.
|
||||
//
|
||||
// A shorthand for:
|
||||
// PushScope()
|
||||
// f(scope)
|
||||
// PopScope()
|
||||
// It is useful when extra data should be sent with a single capture call, for
|
||||
// instance a different level or tags.
|
||||
//
|
||||
// The scope passed to f starts as a clone of the current scope and can be
|
||||
// freely modified without affecting the current scope.
|
||||
//
|
||||
// It is a shorthand for PushScope followed by PopScope.
|
||||
func (hub *Hub) WithScope(f func(scope *Scope)) {
|
||||
scope := hub.PushScope()
|
||||
defer hub.PopScope()
|
||||
f(scope)
|
||||
}
|
||||
|
||||
// ConfigureScope invokes a function that can modify the current scope.
|
||||
// ConfigureScope runs f in the current scope.
|
||||
//
|
||||
// The function is passed a mutable reference to the `Scope` so that modifications
|
||||
// can be performed.
|
||||
// It is useful to set data that applies to all events that share the current
|
||||
// scope.
|
||||
//
|
||||
// Modifying the scope affects all references to the current scope.
|
||||
//
|
||||
// See also WithScope for making isolated temporary changes.
|
||||
func (hub *Hub) ConfigureScope(f func(scope *Scope)) {
|
||||
scope := hub.Scope()
|
||||
f(scope)
|
||||
}
|
||||
|
||||
// CaptureEvent calls the method of a same name on currently bound `Client` instance
|
||||
// passing it a top-level `Scope`.
|
||||
// Returns `EventID` if successfully, or `nil` if there's no `Scope` or `Client` available.
|
||||
// CaptureEvent calls the method of a same name on currently bound Client instance
|
||||
// passing it a top-level Scope.
|
||||
// Returns EventID if successfully, or nil if there's no Scope or Client available.
|
||||
func (hub *Hub) CaptureEvent(event *Event) *EventID {
|
||||
client, scope := hub.Client(), hub.Scope()
|
||||
if client == nil || scope == nil {
|
||||
return nil
|
||||
}
|
||||
eventID := client.CaptureEvent(event, nil, scope)
|
||||
|
||||
hub.mu.Lock()
|
||||
defer hub.mu.Unlock()
|
||||
if eventID != nil {
|
||||
hub.lastEventID = *eventID
|
||||
} else {
|
||||
@@ -219,15 +236,18 @@ func (hub *Hub) CaptureEvent(event *Event) *EventID {
|
||||
return eventID
|
||||
}
|
||||
|
||||
// CaptureMessage calls the method of a same name on currently bound `Client` instance
|
||||
// passing it a top-level `Scope`.
|
||||
// Returns `EventID` if successfully, or `nil` if there's no `Scope` or `Client` available.
|
||||
// CaptureMessage calls the method of a same name on currently bound Client instance
|
||||
// passing it a top-level Scope.
|
||||
// Returns EventID if successfully, or nil if there's no Scope or Client available.
|
||||
func (hub *Hub) CaptureMessage(message string) *EventID {
|
||||
client, scope := hub.Client(), hub.Scope()
|
||||
if client == nil || scope == nil {
|
||||
return nil
|
||||
}
|
||||
eventID := client.CaptureMessage(message, nil, scope)
|
||||
|
||||
hub.mu.Lock()
|
||||
defer hub.mu.Unlock()
|
||||
if eventID != nil {
|
||||
hub.lastEventID = *eventID
|
||||
} else {
|
||||
@@ -236,15 +256,18 @@ func (hub *Hub) CaptureMessage(message string) *EventID {
|
||||
return eventID
|
||||
}
|
||||
|
||||
// CaptureException calls the method of a same name on currently bound `Client` instance
|
||||
// passing it a top-level `Scope`.
|
||||
// Returns `EventID` if successfully, or `nil` if there's no `Scope` or `Client` available.
|
||||
// CaptureException calls the method of a same name on currently bound Client instance
|
||||
// passing it a top-level Scope.
|
||||
// Returns EventID if successfully, or nil if there's no Scope or Client available.
|
||||
func (hub *Hub) CaptureException(exception error) *EventID {
|
||||
client, scope := hub.Client(), hub.Scope()
|
||||
if client == nil || scope == nil {
|
||||
return nil
|
||||
}
|
||||
eventID := client.CaptureException(exception, &EventHint{OriginalException: exception}, scope)
|
||||
|
||||
hub.mu.Lock()
|
||||
defer hub.mu.Unlock()
|
||||
if eventID != nil {
|
||||
hub.lastEventID = *eventID
|
||||
} else {
|
||||
@@ -294,9 +317,9 @@ func (hub *Hub) AddBreadcrumb(breadcrumb *Breadcrumb, hint *BreadcrumbHint) {
|
||||
hub.Scope().AddBreadcrumb(breadcrumb, max)
|
||||
}
|
||||
|
||||
// Recover calls the method of a same name on currently bound `Client` instance
|
||||
// passing it a top-level `Scope`.
|
||||
// Returns `EventID` if successfully, or `nil` if there's no `Scope` or `Client` available.
|
||||
// Recover calls the method of a same name on currently bound Client instance
|
||||
// passing it a top-level Scope.
|
||||
// Returns EventID if successfully, or nil if there's no Scope or Client available.
|
||||
func (hub *Hub) Recover(err interface{}) *EventID {
|
||||
if err == nil {
|
||||
err = recover()
|
||||
@@ -308,9 +331,9 @@ func (hub *Hub) Recover(err interface{}) *EventID {
|
||||
return client.Recover(err, &EventHint{RecoveredException: err}, scope)
|
||||
}
|
||||
|
||||
// RecoverWithContext calls the method of a same name on currently bound `Client` instance
|
||||
// passing it a top-level `Scope`.
|
||||
// Returns `EventID` if successfully, or `nil` if there's no `Scope` or `Client` available.
|
||||
// RecoverWithContext calls the method of a same name on currently bound Client instance
|
||||
// passing it a top-level Scope.
|
||||
// Returns EventID if successfully, or nil if there's no Scope or Client available.
|
||||
func (hub *Hub) RecoverWithContext(ctx context.Context, err interface{}) *EventID {
|
||||
if err == nil {
|
||||
err = recover()
|
||||
@@ -343,14 +366,14 @@ func (hub *Hub) Flush(timeout time.Duration) bool {
|
||||
return client.Flush(timeout)
|
||||
}
|
||||
|
||||
// HasHubOnContext checks whether `Hub` instance is bound to a given `Context` struct.
|
||||
// HasHubOnContext checks whether Hub instance is bound to a given Context struct.
|
||||
func HasHubOnContext(ctx context.Context) bool {
|
||||
_, ok := ctx.Value(HubContextKey).(*Hub)
|
||||
return ok
|
||||
}
|
||||
|
||||
// GetHubFromContext tries to retrieve `Hub` instance from the given `Context` struct
|
||||
// or return `nil` if one is not found.
|
||||
// GetHubFromContext tries to retrieve Hub instance from the given Context struct
|
||||
// or return nil if one is not found.
|
||||
func GetHubFromContext(ctx context.Context) *Hub {
|
||||
if hub, ok := ctx.Value(HubContextKey).(*Hub); ok {
|
||||
return hub
|
||||
@@ -358,7 +381,7 @@ func GetHubFromContext(ctx context.Context) *Hub {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetHubOnContext stores given `Hub` instance on the `Context` struct and returns a new `Context`.
|
||||
// SetHubOnContext stores given Hub instance on the Context struct and returns a new Context.
|
||||
func SetHubOnContext(ctx context.Context, hub *Hub) context.Context {
|
||||
return context.WithValue(ctx, HubContextKey, hub)
|
||||
}
|
||||
|
||||
50
vendor/github.com/getsentry/sentry-go/integrations.go
сгенерированный
поставляемый
50
vendor/github.com/getsentry/sentry-go/integrations.go
сгенерированный
поставляемый
@@ -70,27 +70,49 @@ func (ei *environmentIntegration) SetupOnce(client *Client) {
|
||||
}
|
||||
|
||||
func (ei *environmentIntegration) processor(event *Event, hint *EventHint) *Event {
|
||||
// Initialize maps as necessary.
|
||||
if event.Contexts == nil {
|
||||
event.Contexts = make(map[string]interface{})
|
||||
}
|
||||
|
||||
event.Contexts["device"] = map[string]interface{}{
|
||||
"arch": runtime.GOARCH,
|
||||
"num_cpu": runtime.NumCPU(),
|
||||
for _, name := range []string{"device", "os", "runtime"} {
|
||||
if event.Contexts[name] == nil {
|
||||
event.Contexts[name] = make(map[string]interface{})
|
||||
}
|
||||
}
|
||||
|
||||
event.Contexts["os"] = map[string]interface{}{
|
||||
"name": runtime.GOOS,
|
||||
// Set contextual information preserving existing data. For each context, if
|
||||
// the existing value is not of type map[string]interface{}, then no
|
||||
// additional information is added.
|
||||
if deviceContext, ok := event.Contexts["device"].(map[string]interface{}); ok {
|
||||
if _, ok := deviceContext["arch"]; !ok {
|
||||
deviceContext["arch"] = runtime.GOARCH
|
||||
}
|
||||
if _, ok := deviceContext["num_cpu"]; !ok {
|
||||
deviceContext["num_cpu"] = runtime.NumCPU()
|
||||
}
|
||||
}
|
||||
|
||||
event.Contexts["runtime"] = map[string]interface{}{
|
||||
"name": "go",
|
||||
"version": runtime.Version(),
|
||||
"go_numroutines": runtime.NumGoroutine(),
|
||||
"go_maxprocs": runtime.GOMAXPROCS(0),
|
||||
"go_numcgocalls": runtime.NumCgoCall(),
|
||||
if osContext, ok := event.Contexts["os"].(map[string]interface{}); ok {
|
||||
if _, ok := osContext["name"]; !ok {
|
||||
osContext["name"] = runtime.GOOS
|
||||
}
|
||||
}
|
||||
if runtimeContext, ok := event.Contexts["runtime"].(map[string]interface{}); ok {
|
||||
if _, ok := runtimeContext["name"]; !ok {
|
||||
runtimeContext["name"] = "go"
|
||||
}
|
||||
if _, ok := runtimeContext["version"]; !ok {
|
||||
runtimeContext["version"] = runtime.Version()
|
||||
}
|
||||
if _, ok := runtimeContext["go_numroutines"]; !ok {
|
||||
runtimeContext["go_numroutines"] = runtime.NumGoroutine()
|
||||
}
|
||||
if _, ok := runtimeContext["go_maxprocs"]; !ok {
|
||||
runtimeContext["go_maxprocs"] = runtime.GOMAXPROCS(0)
|
||||
}
|
||||
if _, ok := runtimeContext["go_numcgocalls"]; !ok {
|
||||
runtimeContext["go_numcgocalls"] = runtime.NumCgoCall()
|
||||
}
|
||||
}
|
||||
|
||||
return event
|
||||
}
|
||||
|
||||
|
||||
126
vendor/github.com/getsentry/sentry-go/interfaces.go
сгенерированный
поставляемый
126
vendor/github.com/getsentry/sentry-go/interfaces.go
сгенерированный
поставляемый
@@ -13,9 +13,13 @@ import (
|
||||
// Protocol Docs (kinda)
|
||||
// https://github.com/getsentry/rust-sentry-types/blob/master/src/protocol/v7.rs
|
||||
|
||||
// Level marks the severity of the event
|
||||
// transactionType is the type of a transaction event.
|
||||
const transactionType = "transaction"
|
||||
|
||||
// Level marks the severity of the event.
|
||||
type Level string
|
||||
|
||||
// Describes the severity of the event.
|
||||
const (
|
||||
LevelDebug Level = "debug"
|
||||
LevelInfo Level = "info"
|
||||
@@ -24,7 +28,7 @@ const (
|
||||
LevelFatal Level = "fatal"
|
||||
)
|
||||
|
||||
// https://docs.sentry.io/development/sdk-dev/event-payloads/sdk/
|
||||
// SdkInfo contains all metadata about about the SDK being used.
|
||||
type SdkInfo struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
@@ -32,6 +36,7 @@ type SdkInfo struct {
|
||||
Packages []SdkPackage `json:"packages,omitempty"`
|
||||
}
|
||||
|
||||
// SdkPackage describes a package that was installed.
|
||||
type SdkPackage struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
@@ -39,10 +44,13 @@ type SdkPackage struct {
|
||||
|
||||
// TODO: This type could be more useful, as map of interface{} is too generic
|
||||
// and requires a lot of type assertions in beforeBreadcrumb calls
|
||||
// plus it could just be `map[string]interface{}` then
|
||||
// plus it could just be map[string]interface{} then.
|
||||
|
||||
// BreadcrumbHint contains information that can be associated with a Breadcrumb.
|
||||
type BreadcrumbHint map[string]interface{}
|
||||
|
||||
// https://docs.sentry.io/development/sdk-dev/event-payloads/breadcrumbs/
|
||||
// Breadcrumb specifies an application event that occurred before a Sentry event.
|
||||
// An event may contain one or more breadcrumbs.
|
||||
type Breadcrumb struct {
|
||||
Category string `json:"category,omitempty"`
|
||||
Data map[string]interface{} `json:"data,omitempty"`
|
||||
@@ -52,6 +60,7 @@ type Breadcrumb struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON converts the Breadcrumb struct to JSON.
|
||||
func (b *Breadcrumb) MarshalJSON() ([]byte, error) {
|
||||
type alias Breadcrumb
|
||||
// encoding/json doesn't support the "omitempty" option for struct types.
|
||||
@@ -67,14 +76,11 @@ func (b *Breadcrumb) MarshalJSON() ([]byte, error) {
|
||||
alias: (*alias)(b),
|
||||
})
|
||||
}
|
||||
return json.Marshal(&struct {
|
||||
*alias
|
||||
}{
|
||||
alias: (*alias)(b),
|
||||
})
|
||||
return json.Marshal((*alias)(b))
|
||||
}
|
||||
|
||||
// https://docs.sentry.io/development/sdk-dev/event-payloads/user/
|
||||
// User describes the user associated with an Event. If this is used, at least
|
||||
// an ID or an IP address should be provided.
|
||||
type User struct {
|
||||
Email string `json:"email,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
@@ -82,7 +88,7 @@ type User struct {
|
||||
Username string `json:"username,omitempty"`
|
||||
}
|
||||
|
||||
// https://docs.sentry.io/development/sdk-dev/event-payloads/request/
|
||||
// Request contains information on a HTTP request related to the event.
|
||||
type Request struct {
|
||||
URL string `json:"url,omitempty"`
|
||||
Method string `json:"method,omitempty"`
|
||||
@@ -131,7 +137,7 @@ func NewRequest(r *http.Request) *Request {
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.sentry.io/development/sdk-dev/event-payloads/exception/
|
||||
// Exception specifies an error that occurred.
|
||||
type Exception struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
Value string `json:"value,omitempty"`
|
||||
@@ -141,9 +147,11 @@ type Exception struct {
|
||||
RawStacktrace *Stacktrace `json:"raw_stacktrace,omitempty"`
|
||||
}
|
||||
|
||||
// EventID is a hexadecimal string representing a unique uuid4 for an Event.
|
||||
// An EventID must be 32 characters long, lowercase and not have any dashes.
|
||||
type EventID string
|
||||
|
||||
// https://docs.sentry.io/development/sdk-dev/event-payloads/
|
||||
// Event is the fundamental data structure that is sent to Sentry.
|
||||
type Event struct {
|
||||
Breadcrumbs []*Breadcrumb `json:"breadcrumbs,omitempty"`
|
||||
Contexts map[string]interface{} `json:"contexts,omitempty"`
|
||||
@@ -167,30 +175,57 @@ type Event struct {
|
||||
Modules map[string]string `json:"modules,omitempty"`
|
||||
Request *Request `json:"request,omitempty"`
|
||||
Exception []Exception `json:"exception,omitempty"`
|
||||
|
||||
// Experimental: This is part of a beta feature of the SDK. The fields below
|
||||
// are only relevant for transactions.
|
||||
Type string `json:"type,omitempty"`
|
||||
StartTimestamp time.Time `json:"start_timestamp"`
|
||||
Spans []*Span `json:"spans,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON converts the Event struct to JSON.
|
||||
func (e *Event) MarshalJSON() ([]byte, error) {
|
||||
type alias Event
|
||||
// encoding/json doesn't support the "omitempty" option for struct types.
|
||||
// See https://golang.org/issues/11939.
|
||||
// This implementation of MarshalJSON shadows the original Timestamp field
|
||||
// forcing it to be omitted when the Timestamp is the zero value of
|
||||
// time.Time.
|
||||
if e.Timestamp.IsZero() {
|
||||
return json.Marshal(&struct {
|
||||
*alias
|
||||
Timestamp json.RawMessage `json:"timestamp,omitempty"`
|
||||
}{
|
||||
alias: (*alias)(e),
|
||||
})
|
||||
// event aliases Event to allow calling json.Marshal without an infinite
|
||||
// loop. It preserves all fields of Event while none of the attached
|
||||
// methods.
|
||||
type event Event
|
||||
|
||||
// Transactions are marshaled in the standard way how json.Marshal works.
|
||||
if e.Type == transactionType {
|
||||
return json.Marshal((*event)(e))
|
||||
}
|
||||
return json.Marshal(&struct {
|
||||
*alias
|
||||
}{
|
||||
alias: (*alias)(e),
|
||||
})
|
||||
|
||||
// errorEvent is like Event with some shadowed fields for customizing the
|
||||
// JSON serialization of regular "error events".
|
||||
type errorEvent struct {
|
||||
*event
|
||||
|
||||
// encoding/json doesn't support the omitempty option for struct types.
|
||||
// See https://golang.org/issues/11939.
|
||||
// We shadow the original Event.Timestamp field with a json.RawMessage.
|
||||
// This allows us to include the timestamp when non-zero and omit it
|
||||
// otherwise.
|
||||
Timestamp json.RawMessage `json:"timestamp,omitempty"`
|
||||
|
||||
// The fields below are not part of the regular "error events" and only
|
||||
// make sense to be sent for transactions. They shadow the respective
|
||||
// fields in Event and are meant to remain nil, triggering the omitempty
|
||||
// behavior.
|
||||
Type json.RawMessage `json:"type,omitempty"`
|
||||
StartTimestamp json.RawMessage `json:"start_timestamp,omitempty"`
|
||||
Spans json.RawMessage `json:"spans,omitempty"`
|
||||
}
|
||||
|
||||
x := &errorEvent{event: (*event)(e)}
|
||||
if !e.Timestamp.IsZero() {
|
||||
x.Timestamp = append(x.Timestamp, '"')
|
||||
x.Timestamp = e.Timestamp.UTC().AppendFormat(x.Timestamp, time.RFC3339Nano)
|
||||
x.Timestamp = append(x.Timestamp, '"')
|
||||
}
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
// NewEvent creates a new Event.
|
||||
func NewEvent() *Event {
|
||||
event := Event{
|
||||
Contexts: make(map[string]interface{}),
|
||||
@@ -201,6 +236,7 @@ func NewEvent() *Event {
|
||||
return &event
|
||||
}
|
||||
|
||||
// Thread specifies threads that were running at the time of an event.
|
||||
type Thread struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
@@ -210,6 +246,7 @@ type Thread struct {
|
||||
Current bool `json:"current,omitempty"`
|
||||
}
|
||||
|
||||
// EventHint contains information that can be associated with an Event.
|
||||
type EventHint struct {
|
||||
Data interface{}
|
||||
EventID string
|
||||
@@ -219,3 +256,30 @@ type EventHint struct {
|
||||
Request *http.Request
|
||||
Response *http.Response
|
||||
}
|
||||
|
||||
// TraceContext describes the context of the trace.
|
||||
//
|
||||
// Experimental: This is part of a beta feature of the SDK.
|
||||
type TraceContext struct {
|
||||
TraceID string `json:"trace_id"`
|
||||
SpanID string `json:"span_id"`
|
||||
Op string `json:"op,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// Span describes a timed unit of work in a trace.
|
||||
//
|
||||
// Experimental: This is part of a beta feature of the SDK.
|
||||
type Span struct {
|
||||
TraceID string `json:"trace_id"`
|
||||
SpanID string `json:"span_id"`
|
||||
ParentSpanID string `json:"parent_span_id,omitempty"`
|
||||
Op string `json:"op,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Tags map[string]string `json:"tags,omitempty"`
|
||||
StartTimestamp time.Time `json:"start_timestamp"`
|
||||
EndTimestamp time.Time `json:"timestamp"`
|
||||
Data map[string]interface{} `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
21
vendor/github.com/getsentry/sentry-go/scope.go
сгенерированный
поставляемый
21
vendor/github.com/getsentry/sentry-go/scope.go
сгенерированный
поставляемый
@@ -11,19 +11,18 @@ import (
|
||||
|
||||
// Scope holds contextual data for the current scope.
|
||||
//
|
||||
// The scope is an object that can cloned efficiently and stores data that
|
||||
// is locally relevant to an event. For instance the scope will hold recorded
|
||||
// The scope is an object that can cloned efficiently and stores data that is
|
||||
// locally relevant to an event. For instance the scope will hold recorded
|
||||
// breadcrumbs and similar information.
|
||||
//
|
||||
// The scope can be interacted with in two ways:
|
||||
// The scope can be interacted with in two ways. First, the scope is routinely
|
||||
// updated with information by functions such as AddBreadcrumb which will modify
|
||||
// the current scope. Second, the current scope can be configured through the
|
||||
// ConfigureScope function or Hub method of the same name.
|
||||
//
|
||||
// 1. the scope is routinely updated with information by functions such as
|
||||
// `AddBreadcrumb` which will modify the currently top-most scope.
|
||||
// 2. the topmost scope can also be configured through the `ConfigureScope`
|
||||
// method.
|
||||
//
|
||||
// Note that the scope can only be modified but not inspected.
|
||||
// Only the client can use the scope to extract information currently.
|
||||
// The scope is meant to be modified but not inspected directly. When preparing
|
||||
// an event for reporting, the current client adds information from the current
|
||||
// scope into the event.
|
||||
type Scope struct {
|
||||
mu sync.RWMutex
|
||||
breadcrumbs []*Breadcrumb
|
||||
@@ -47,6 +46,7 @@ type Scope struct {
|
||||
eventProcessors []EventProcessor
|
||||
}
|
||||
|
||||
// NewScope creates a new Scope.
|
||||
func NewScope() *Scope {
|
||||
scope := Scope{
|
||||
breadcrumbs: make([]*Breadcrumb, 0),
|
||||
@@ -309,6 +309,7 @@ func (scope *Scope) Clone() *Scope {
|
||||
clone.level = scope.level
|
||||
clone.transaction = scope.transaction
|
||||
clone.request = scope.request
|
||||
clone.requestBody = scope.requestBody
|
||||
|
||||
return clone
|
||||
}
|
||||
|
||||
28
vendor/github.com/getsentry/sentry-go/sentry.go
сгенерированный
поставляемый
28
vendor/github.com/getsentry/sentry-go/sentry.go
сгенерированный
поставляемый
@@ -5,14 +5,15 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Version is the version of the sentry-go SDK.
|
||||
const Version = "0.6.1"
|
||||
// Version is the version of the SDK.
|
||||
const Version = "0.7.0"
|
||||
|
||||
// apiVersion is the minimum version of the Sentry API compatible with the
|
||||
// sentry-go SDK.
|
||||
const apiVersion = "7"
|
||||
|
||||
// Init initializes whole SDK by creating new `Client` and binding it to the current `Hub`
|
||||
// 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 {
|
||||
hub := CurrentHub()
|
||||
client, err := NewClient(options)
|
||||
@@ -47,7 +48,7 @@ func CaptureException(exception error) *EventID {
|
||||
// CaptureEvent captures an event on the currently active client if any.
|
||||
//
|
||||
// The event must already be assembled. Typically code would instead use
|
||||
// the utility methods like `CaptureException`. The return value is the
|
||||
// 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(event *Event) *EventID {
|
||||
hub := CurrentHub()
|
||||
@@ -63,7 +64,7 @@ func Recover() *EventID {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Recover captures a panic and passes relevant context object.
|
||||
// RecoverWithContext captures a panic and passes relevant context object.
|
||||
func RecoverWithContext(ctx context.Context) *EventID {
|
||||
if err := recover(); err != nil {
|
||||
var hub *Hub
|
||||
@@ -79,34 +80,25 @@ func RecoverWithContext(ctx context.Context) *EventID {
|
||||
return nil
|
||||
}
|
||||
|
||||
// WithScope temporarily pushes a scope for a single call.
|
||||
//
|
||||
// This function takes one argument, a callback that executes
|
||||
// in the context of that scope.
|
||||
//
|
||||
// This is useful when extra data should be send with a single capture call
|
||||
// for instance a different level or tags
|
||||
// WithScope is a shorthand for CurrentHub().WithScope.
|
||||
func WithScope(f func(scope *Scope)) {
|
||||
hub := CurrentHub()
|
||||
hub.WithScope(f)
|
||||
}
|
||||
|
||||
// ConfigureScope invokes a function that can modify the current scope.
|
||||
//
|
||||
// The function is passed a mutable reference to the `Scope` so that modifications
|
||||
// can be performed.
|
||||
// ConfigureScope is a shorthand for CurrentHub().ConfigureScope.
|
||||
func ConfigureScope(f func(scope *Scope)) {
|
||||
hub := CurrentHub()
|
||||
hub.ConfigureScope(f)
|
||||
}
|
||||
|
||||
// PushScope pushes a new scope.
|
||||
// PushScope is a shorthand for CurrentHub().PushPushScope.
|
||||
func PushScope() {
|
||||
hub := CurrentHub()
|
||||
hub.PushScope()
|
||||
}
|
||||
|
||||
// PopScope pushes a new scope.
|
||||
// PopScope is a shorthand for CurrentHub().PopScope.
|
||||
func PopScope() {
|
||||
hub := CurrentHub()
|
||||
hub.PopScope()
|
||||
|
||||
3
vendor/github.com/getsentry/sentry-go/sourcereader.go
сгенерированный
поставляемый
3
vendor/github.com/getsentry/sentry-go/sourcereader.go
сгенерированный
поставляемый
@@ -36,11 +36,12 @@ func (sr *sourceReader) readContextLines(filename string, line, context int) ([]
|
||||
return sr.calculateContextLines(lines, line, context)
|
||||
}
|
||||
|
||||
// `contextLine` points to a line that caused an issue itself, in relation to returned slice
|
||||
func (sr *sourceReader) calculateContextLines(lines [][]byte, line, context int) ([][]byte, int) {
|
||||
// Stacktrace lines are 1-indexed, slices are 0-indexed
|
||||
line--
|
||||
|
||||
// contextLine points to a line that caused an issue itself, in relation to
|
||||
// returned slice.
|
||||
contextLine := context
|
||||
|
||||
if lines == nil || line >= len(lines) || line < 0 {
|
||||
|
||||
91
vendor/github.com/getsentry/sentry-go/stacktrace.go
сгенерированный
поставляемый
91
vendor/github.com/getsentry/sentry-go/stacktrace.go
сгенерированный
поставляемый
@@ -23,7 +23,7 @@ type Stacktrace struct {
|
||||
FramesOmitted []uint `json:"frames_omitted,omitempty"`
|
||||
}
|
||||
|
||||
// NewStacktrace creates a stacktrace using `runtime.Callers`.
|
||||
// NewStacktrace creates a stacktrace using runtime.Callers.
|
||||
func NewStacktrace() *Stacktrace {
|
||||
pcs := make([]uintptr, 100)
|
||||
n := runtime.Callers(1, pcs)
|
||||
@@ -42,17 +42,21 @@ func NewStacktrace() *Stacktrace {
|
||||
return &stacktrace
|
||||
}
|
||||
|
||||
// ExtractStacktrace creates a new `Stacktrace` based on the given `error` object.
|
||||
// TODO: Make it configurable so that anyone can provide their own implementation?
|
||||
// Use of reflection allows us to not have a hard dependency on any given package, so we don't have to import it
|
||||
// Use of reflection allows us to not have a hard dependency on any given
|
||||
// package, so we don't have to import it.
|
||||
|
||||
// ExtractStacktrace creates a new Stacktrace based on the given error.
|
||||
func ExtractStacktrace(err error) *Stacktrace {
|
||||
method := extractReflectedStacktraceMethod(err)
|
||||
|
||||
if !method.IsValid() {
|
||||
return nil
|
||||
}
|
||||
var pcs []uintptr
|
||||
|
||||
pcs := extractPcs(method)
|
||||
if method.IsValid() {
|
||||
pcs = extractPcs(method)
|
||||
} else {
|
||||
pcs = extractXErrorsPC(err)
|
||||
}
|
||||
|
||||
if len(pcs) == 0 {
|
||||
return nil
|
||||
@@ -127,7 +131,34 @@ func extractPcs(method reflect.Value) []uintptr {
|
||||
return pcs
|
||||
}
|
||||
|
||||
// https://docs.sentry.io/development/sdk-dev/event-payloads/stacktrace/
|
||||
// extractXErrorsPC extracts program counters from error values compatible with
|
||||
// the error types from golang.org/x/xerrors.
|
||||
//
|
||||
// It returns nil if err is not compatible with errors from that package or if
|
||||
// no program counters are stored in err.
|
||||
func extractXErrorsPC(err error) []uintptr {
|
||||
// This implementation uses the reflect package to avoid a hard dependency
|
||||
// on third-party packages.
|
||||
|
||||
// We don't know if err matches the expected type. For simplicity, instead
|
||||
// of trying to account for all possible ways things can go wrong, some
|
||||
// assumptions are made and if they are violated the code will panic. We
|
||||
// recover from any panic and ignore it, returning nil.
|
||||
//nolint: errcheck
|
||||
defer func() { recover() }()
|
||||
|
||||
field := reflect.ValueOf(err).Elem().FieldByName("frame") // type Frame struct{ frames [3]uintptr }
|
||||
field = field.FieldByName("frames")
|
||||
field = field.Slice(1, field.Len()) // drop first pc pointing to xerrors.New
|
||||
pc := make([]uintptr, field.Len())
|
||||
for i := 0; i < field.Len(); i++ {
|
||||
pc[i] = uintptr(field.Index(i).Uint())
|
||||
}
|
||||
return pc
|
||||
}
|
||||
|
||||
// Frame represents a function call and it's metadata. Frames are associated
|
||||
// with a Stacktrace.
|
||||
type Frame struct {
|
||||
Function string `json:"function,omitempty"`
|
||||
Symbol string `json:"symbol,omitempty"`
|
||||
@@ -144,30 +175,46 @@ type Frame struct {
|
||||
Vars map[string]interface{} `json:"vars,omitempty"`
|
||||
}
|
||||
|
||||
// NewFrame assembles a stacktrace frame out of `runtime.Frame`.
|
||||
// NewFrame assembles a stacktrace frame out of runtime.Frame.
|
||||
func NewFrame(f runtime.Frame) Frame {
|
||||
abspath := f.File
|
||||
filename := f.File
|
||||
var abspath, relpath string
|
||||
// NOTE: f.File paths historically use forward slash as path separator even
|
||||
// on Windows, though this is not yet documented, see
|
||||
// https://golang.org/issues/3335. In any case, filepath.IsAbs can work with
|
||||
// paths with either slash or backslash on Windows.
|
||||
switch {
|
||||
case f.File == "":
|
||||
relpath = unknown
|
||||
// Leave abspath as the empty string to be omitted when serializing
|
||||
// event as JSON.
|
||||
abspath = ""
|
||||
case filepath.IsAbs(f.File):
|
||||
abspath = f.File
|
||||
// TODO: in the general case, it is not trivial to come up with a
|
||||
// "project relative" path with the data we have in run time.
|
||||
// We shall not use filepath.Base because it creates ambiguous paths and
|
||||
// affects the "Suspect Commits" feature.
|
||||
// For now, leave relpath empty to be omitted when serializing the event
|
||||
// as JSON. Improve this later.
|
||||
relpath = ""
|
||||
default:
|
||||
// f.File is a relative path. This may happen when the binary is built
|
||||
// with the -trimpath flag.
|
||||
relpath = f.File
|
||||
// Omit abspath when serializing the event as JSON.
|
||||
abspath = ""
|
||||
}
|
||||
|
||||
function := f.Function
|
||||
var pkg string
|
||||
|
||||
if filename != "" {
|
||||
filename = filepath.Base(filename)
|
||||
} else {
|
||||
filename = unknown
|
||||
}
|
||||
|
||||
if abspath == "" {
|
||||
abspath = unknown
|
||||
}
|
||||
|
||||
if function != "" {
|
||||
pkg, function = splitQualifiedFunctionName(function)
|
||||
}
|
||||
|
||||
frame := Frame{
|
||||
AbsPath: abspath,
|
||||
Filename: filename,
|
||||
Filename: relpath,
|
||||
Lineno: f.Line,
|
||||
Module: pkg,
|
||||
Function: function,
|
||||
|
||||
82
vendor/github.com/getsentry/sentry-go/transport.go
сгенерированный
поставляемый
82
vendor/github.com/getsentry/sentry-go/transport.go
сгенерированный
поставляемый
@@ -4,6 +4,8 @@ import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
@@ -15,7 +17,7 @@ const defaultBufferSize = 30
|
||||
const defaultRetryAfter = time.Second * 60
|
||||
const defaultTimeout = time.Second * 30
|
||||
|
||||
// Transport is used by the `Client` to deliver events to remote server.
|
||||
// Transport is used by the Client to deliver events to remote server.
|
||||
type Transport interface {
|
||||
Flush(timeout time.Duration) bool
|
||||
Configure(options ClientOptions)
|
||||
@@ -70,8 +72,10 @@ func getRequestBodyFromEvent(event *Event) []byte {
|
||||
return body
|
||||
}
|
||||
|
||||
partialMarshallMessage := "Original event couldn't be marshalled. Succeeded by stripping the data " +
|
||||
"that uses interface{} type. Please verify that the data you attach to the scope is serializable."
|
||||
partialMarshallMessage := fmt.Sprintf("Could not encode original event as JSON. "+
|
||||
"Succeeded by removing Breadcrumbs, Contexts and Extra. "+
|
||||
"Please verify the data you attach to the scope. "+
|
||||
"Error: %s", err)
|
||||
// Try to serialize the event, with all the contextual data that allows for interface{} stripped.
|
||||
event.Breadcrumbs = nil
|
||||
event.Contexts = nil
|
||||
@@ -92,6 +96,40 @@ func getRequestBodyFromEvent(event *Event) []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getEnvelopeFromBody(body []byte, now time.Time) *bytes.Buffer {
|
||||
var b bytes.Buffer
|
||||
fmt.Fprintf(&b, `{"sent_at":"%s"}`, now.UTC().Format(time.RFC3339Nano))
|
||||
fmt.Fprint(&b, "\n", `{"type":"transaction"}`, "\n")
|
||||
b.Write(body)
|
||||
return &b
|
||||
}
|
||||
|
||||
func getRequestFromEvent(event *Event, dsn *Dsn) (*http.Request, error) {
|
||||
body := getRequestBodyFromEvent(event)
|
||||
if body == nil {
|
||||
return nil, errors.New("event could not be marshalled")
|
||||
}
|
||||
|
||||
if event.Type == transactionType {
|
||||
env := getEnvelopeFromBody(body, time.Now())
|
||||
request, _ := http.NewRequest(
|
||||
http.MethodPost,
|
||||
dsn.EnvelopeAPIURL().String(),
|
||||
env,
|
||||
)
|
||||
|
||||
return request, nil
|
||||
}
|
||||
|
||||
request, _ := http.NewRequest(
|
||||
http.MethodPost,
|
||||
dsn.StoreAPIURL().String(),
|
||||
bytes.NewBuffer(body),
|
||||
)
|
||||
|
||||
return request, nil
|
||||
}
|
||||
|
||||
// ================================
|
||||
// HTTPTransport
|
||||
// ================================
|
||||
@@ -103,7 +141,7 @@ type batch struct {
|
||||
done chan struct{} // closed to signal completion of all items
|
||||
}
|
||||
|
||||
// HTTPTransport is a default implementation of `Transport` interface used by `Client`.
|
||||
// HTTPTransport is a default implementation of Transport interface used by Client.
|
||||
type HTTPTransport struct {
|
||||
dsn *Dsn
|
||||
client *http.Client
|
||||
@@ -124,7 +162,7 @@ type HTTPTransport struct {
|
||||
disabledUntil time.Time
|
||||
}
|
||||
|
||||
// NewHTTPTransport returns a new pre-configured instance of HTTPTransport
|
||||
// NewHTTPTransport returns a new pre-configured instance of HTTPTransport.
|
||||
func NewHTTPTransport() *HTTPTransport {
|
||||
transport := HTTPTransport{
|
||||
BufferSize: defaultBufferSize,
|
||||
@@ -133,7 +171,7 @@ func NewHTTPTransport() *HTTPTransport {
|
||||
return &transport
|
||||
}
|
||||
|
||||
// Configure is called by the `Client` itself, providing it it's own `ClientOptions`.
|
||||
// Configure is called by the Client itself, providing it it's own ClientOptions.
|
||||
func (t *HTTPTransport) Configure(options ClientOptions) {
|
||||
dsn, err := NewDsn(options.Dsn)
|
||||
if err != nil {
|
||||
@@ -175,7 +213,7 @@ func (t *HTTPTransport) Configure(options ClientOptions) {
|
||||
})
|
||||
}
|
||||
|
||||
// SendEvent assembles a new packet out of `Event` and sends it to remote server.
|
||||
// SendEvent assembles a new packet out of Event and sends it to remote server.
|
||||
func (t *HTTPTransport) SendEvent(event *Event) {
|
||||
if t.dsn == nil {
|
||||
return
|
||||
@@ -187,17 +225,11 @@ func (t *HTTPTransport) SendEvent(event *Event) {
|
||||
return
|
||||
}
|
||||
|
||||
body := getRequestBodyFromEvent(event)
|
||||
if body == nil {
|
||||
request, err := getRequestFromEvent(event, t.dsn)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
request, _ := http.NewRequest(
|
||||
http.MethodPost,
|
||||
t.dsn.StoreAPIURL().String(),
|
||||
bytes.NewBuffer(body),
|
||||
)
|
||||
|
||||
for headerKey, headerValue := range t.dsn.RequestHeaders() {
|
||||
request.Header.Set(headerKey, headerValue)
|
||||
}
|
||||
@@ -332,7 +364,7 @@ func (t *HTTPTransport) worker() {
|
||||
// HTTPSyncTransport
|
||||
// ================================
|
||||
|
||||
// HTTPSyncTransport is an implementation of `Transport` interface which blocks after each captured event.
|
||||
// HTTPSyncTransport is an implementation of Transport interface which blocks after each captured event.
|
||||
type HTTPSyncTransport struct {
|
||||
dsn *Dsn
|
||||
client *http.Client
|
||||
@@ -343,7 +375,7 @@ type HTTPSyncTransport struct {
|
||||
Timeout time.Duration
|
||||
}
|
||||
|
||||
// NewHTTPSyncTransport returns a new pre-configured instance of HTTPSyncTransport
|
||||
// NewHTTPSyncTransport returns a new pre-configured instance of HTTPSyncTransport.
|
||||
func NewHTTPSyncTransport() *HTTPSyncTransport {
|
||||
transport := HTTPSyncTransport{
|
||||
Timeout: defaultTimeout,
|
||||
@@ -352,7 +384,7 @@ func NewHTTPSyncTransport() *HTTPSyncTransport {
|
||||
return &transport
|
||||
}
|
||||
|
||||
// Configure is called by the `Client` itself, providing it it's own `ClientOptions`.
|
||||
// Configure is called by the Client itself, providing it it's own ClientOptions.
|
||||
func (t *HTTPSyncTransport) Configure(options ClientOptions) {
|
||||
dsn, err := NewDsn(options.Dsn)
|
||||
if err != nil {
|
||||
@@ -380,23 +412,17 @@ func (t *HTTPSyncTransport) Configure(options ClientOptions) {
|
||||
}
|
||||
}
|
||||
|
||||
// SendEvent assembles a new packet out of `Event` and sends it to remote server.
|
||||
// SendEvent assembles a new packet out of Event and sends it to remote server.
|
||||
func (t *HTTPSyncTransport) SendEvent(event *Event) {
|
||||
if t.dsn == nil || time.Now().Before(t.disabledUntil) {
|
||||
return
|
||||
}
|
||||
|
||||
body := getRequestBodyFromEvent(event)
|
||||
if body == nil {
|
||||
request, err := getRequestFromEvent(event, t.dsn)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
request, _ := http.NewRequest(
|
||||
http.MethodPost,
|
||||
t.dsn.StoreAPIURL().String(),
|
||||
bytes.NewBuffer(body),
|
||||
)
|
||||
|
||||
for headerKey, headerValue := range t.dsn.RequestHeaders() {
|
||||
request.Header.Set(headerKey, headerValue)
|
||||
}
|
||||
@@ -430,7 +456,7 @@ func (t *HTTPSyncTransport) Flush(_ time.Duration) bool {
|
||||
// noopTransport
|
||||
// ================================
|
||||
|
||||
// noopTransport is an implementation of `Transport` interface which drops all the events.
|
||||
// noopTransport is an implementation of Transport interface which drops all the events.
|
||||
// Only used internally when an empty DSN is provided, which effectively disables the SDK.
|
||||
type noopTransport struct{}
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user