Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/getsentry/raven-go/client.go')
-rw-r--r--vendor/github.com/getsentry/raven-go/client.go977
1 files changed, 0 insertions, 977 deletions
diff --git a/vendor/github.com/getsentry/raven-go/client.go b/vendor/github.com/getsentry/raven-go/client.go
deleted file mode 100644
index a2c9a6c35..000000000
--- a/vendor/github.com/getsentry/raven-go/client.go
+++ /dev/null
@@ -1,977 +0,0 @@
-// Package raven implements a client for the Sentry error logging service.
-package raven
-
-import (
- "bytes"
- "compress/zlib"
- "crypto/rand"
- "crypto/tls"
- "encoding/base64"
- "encoding/hex"
- "encoding/json"
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "log"
- mrand "math/rand"
- "net/http"
- "net/url"
- "os"
- "regexp"
- "runtime"
- "strings"
- "sync"
- "time"
-
- "github.com/certifi/gocertifi"
- pkgErrors "github.com/pkg/errors"
-)
-
-const (
- userAgent = "raven-go/1.0"
- timestampFormat = `"2006-01-02T15:04:05.00"`
-)
-
-var (
- ErrPacketDropped = errors.New("raven: packet dropped")
- ErrUnableToUnmarshalJSON = errors.New("raven: unable to unmarshal JSON")
- ErrMissingUser = errors.New("raven: dsn missing public key and/or password")
- ErrMissingProjectID = errors.New("raven: dsn missing project id")
- ErrInvalidSampleRate = errors.New("raven: sample rate should be between 0 and 1")
-)
-
-type Severity string
-
-// http://docs.python.org/2/howto/logging.html#logging-levels
-const (
- DEBUG = Severity("debug")
- INFO = Severity("info")
- WARNING = Severity("warning")
- ERROR = Severity("error")
- FATAL = Severity("fatal")
-)
-
-type Timestamp time.Time
-
-func (t Timestamp) MarshalJSON() ([]byte, error) {
- return []byte(time.Time(t).UTC().Format(timestampFormat)), nil
-}
-
-func (timestamp *Timestamp) UnmarshalJSON(data []byte) error {
- t, err := time.Parse(timestampFormat, string(data))
- if err != nil {
- return err
- }
-
- *timestamp = Timestamp(t)
- return nil
-}
-
-func (timestamp Timestamp) Format(format string) string {
- t := time.Time(timestamp)
- return t.Format(format)
-}
-
-// An Interface is a Sentry interface that will be serialized as JSON.
-// It must implement json.Marshaler or use json struct tags.
-type Interface interface {
- // The Sentry class name. Example: sentry.interfaces.Stacktrace
- Class() string
-}
-
-type Culpriter interface {
- Culprit() string
-}
-
-type Transport interface {
- Send(url, authHeader string, packet *Packet) error
-}
-
-type Extra map[string]interface{}
-
-type outgoingPacket struct {
- packet *Packet
- ch chan error
-}
-
-type Tag struct {
- Key string
- Value string
-}
-
-type Tags []Tag
-
-func (tag *Tag) MarshalJSON() ([]byte, error) {
- return json.Marshal([2]string{tag.Key, tag.Value})
-}
-
-func (t *Tag) UnmarshalJSON(data []byte) error {
- var tag [2]string
- if err := json.Unmarshal(data, &tag); err != nil {
- return err
- }
- *t = Tag{tag[0], tag[1]}
- return nil
-}
-
-func (t *Tags) UnmarshalJSON(data []byte) error {
- var tags []Tag
-
- switch data[0] {
- case '[':
- // Unmarshal into []Tag
- if err := json.Unmarshal(data, &tags); err != nil {
- return err
- }
- case '{':
- // Unmarshal into map[string]string
- tagMap := make(map[string]string)
- if err := json.Unmarshal(data, &tagMap); err != nil {
- return err
- }
-
- // Convert to []Tag
- for k, v := range tagMap {
- tags = append(tags, Tag{k, v})
- }
- default:
- return ErrUnableToUnmarshalJSON
- }
-
- *t = tags
- return nil
-}
-
-// https://docs.getsentry.com/hosted/clientdev/#building-the-json-packet
-type Packet struct {
- // Required
- Message string `json:"message"`
-
- // Required, set automatically by Client.Send/Report via Packet.Init if blank
- EventID string `json:"event_id"`
- Project string `json:"project"`
- Timestamp Timestamp `json:"timestamp"`
- Level Severity `json:"level"`
- Logger string `json:"logger"`
-
- // Optional
- Platform string `json:"platform,omitempty"`
- Culprit string `json:"culprit,omitempty"`
- ServerName string `json:"server_name,omitempty"`
- Release string `json:"release,omitempty"`
- Environment string `json:"environment,omitempty"`
- Tags Tags `json:"tags,omitempty"`
- Modules map[string]string `json:"modules,omitempty"`
- Fingerprint []string `json:"fingerprint,omitempty"`
- Extra Extra `json:"extra,omitempty"`
-
- Interfaces []Interface `json:"-"`
-}
-
-// NewPacket constructs a packet with the specified message and interfaces.
-func NewPacket(message string, interfaces ...Interface) *Packet {
- extra := Extra{}
- setExtraDefaults(extra)
- return &Packet{
- Message: message,
- Interfaces: interfaces,
- Extra: extra,
- }
-}
-
-// NewPacketWithExtra constructs a packet with the specified message, extra information, and interfaces.
-func NewPacketWithExtra(message string, extra Extra, interfaces ...Interface) *Packet {
- if extra == nil {
- extra = Extra{}
- }
- setExtraDefaults(extra)
-
- return &Packet{
- Message: message,
- Interfaces: interfaces,
- Extra: extra,
- }
-}
-
-func setExtraDefaults(extra Extra) Extra {
- extra["runtime.Version"] = runtime.Version()
- extra["runtime.NumCPU"] = runtime.NumCPU()
- extra["runtime.GOMAXPROCS"] = runtime.GOMAXPROCS(0) // 0 just returns the current value
- extra["runtime.NumGoroutine"] = runtime.NumGoroutine()
- return extra
-}
-
-// Init initializes required fields in a packet. It is typically called by
-// Client.Send/Report automatically.
-func (packet *Packet) Init(project string) error {
- if packet.Project == "" {
- packet.Project = project
- }
- if packet.EventID == "" {
- var err error
- packet.EventID, err = uuid()
- if err != nil {
- return err
- }
- }
- if time.Time(packet.Timestamp).IsZero() {
- packet.Timestamp = Timestamp(time.Now())
- }
- if packet.Level == "" {
- packet.Level = ERROR
- }
- if packet.Logger == "" {
- packet.Logger = "root"
- }
- if packet.ServerName == "" {
- packet.ServerName = hostname
- }
- if packet.Platform == "" {
- packet.Platform = "go"
- }
-
- if packet.Culprit == "" {
- for _, inter := range packet.Interfaces {
- if c, ok := inter.(Culpriter); ok {
- packet.Culprit = c.Culprit()
- if packet.Culprit != "" {
- break
- }
- }
- }
- }
-
- return nil
-}
-
-func (packet *Packet) AddTags(tags map[string]string) {
- for k, v := range tags {
- packet.Tags = append(packet.Tags, Tag{k, v})
- }
-}
-
-func uuid() (string, error) {
- id := make([]byte, 16)
- _, err := io.ReadFull(rand.Reader, id)
- if err != nil {
- return "", err
- }
- id[6] &= 0x0F // clear version
- id[6] |= 0x40 // set version to 4 (random uuid)
- id[8] &= 0x3F // clear variant
- id[8] |= 0x80 // set to IETF variant
- return hex.EncodeToString(id), nil
-}
-
-func (packet *Packet) JSON() ([]byte, error) {
- packetJSON, err := json.Marshal(packet)
- if err != nil {
- return nil, err
- }
-
- interfaces := make(map[string]Interface, len(packet.Interfaces))
- for _, inter := range packet.Interfaces {
- if inter != nil {
- interfaces[inter.Class()] = inter
- }
- }
-
- if len(interfaces) > 0 {
- interfaceJSON, err := json.Marshal(interfaces)
- if err != nil {
- return nil, err
- }
- packetJSON[len(packetJSON)-1] = ','
- packetJSON = append(packetJSON, interfaceJSON[1:]...)
- }
-
- return packetJSON, nil
-}
-
-type context struct {
- user *User
- http *Http
- tags map[string]string
-}
-
-func (c *context) setUser(u *User) { c.user = u }
-func (c *context) setHttp(h *Http) { c.http = h }
-func (c *context) setTags(t map[string]string) {
- if c.tags == nil {
- c.tags = make(map[string]string)
- }
- for k, v := range t {
- c.tags[k] = v
- }
-}
-func (c *context) clear() {
- c.user = nil
- c.http = nil
- c.tags = nil
-}
-
-// Return a list of interfaces to be used in appending with the rest
-func (c *context) interfaces() []Interface {
- len, i := 0, 0
- if c.user != nil {
- len++
- }
- if c.http != nil {
- len++
- }
- interfaces := make([]Interface, len)
- if c.user != nil {
- interfaces[i] = c.user
- i++
- }
- if c.http != nil {
- interfaces[i] = c.http
- i++
- }
- return interfaces
-}
-
-// The maximum number of packets that will be buffered waiting to be delivered.
-// Packets will be dropped if the buffer is full. Used by NewClient.
-var MaxQueueBuffer = 100
-
-func newTransport() Transport {
- t := &HTTPTransport{}
- rootCAs, err := gocertifi.CACerts()
- if err != nil {
- log.Println("raven: failed to load root TLS certificates:", err)
- } else {
- t.Client = &http.Client{
- Transport: &http.Transport{
- Proxy: http.ProxyFromEnvironment,
- TLSClientConfig: &tls.Config{RootCAs: rootCAs},
- },
- }
- }
- return t
-}
-
-func newClient(tags map[string]string) *Client {
- client := &Client{
- Transport: newTransport(),
- Tags: tags,
- context: &context{},
- sampleRate: 1.0,
- queue: make(chan *outgoingPacket, MaxQueueBuffer),
- }
- client.SetDSN(os.Getenv("SENTRY_DSN"))
- client.SetRelease(os.Getenv("SENTRY_RELEASE"))
- client.SetEnvironment(os.Getenv("SENTRY_ENVIRONMENT"))
- return client
-}
-
-// New constructs a new Sentry client instance
-func New(dsn string) (*Client, error) {
- client := newClient(nil)
- return client, client.SetDSN(dsn)
-}
-
-// NewWithTags constructs a new Sentry client instance with default tags.
-func NewWithTags(dsn string, tags map[string]string) (*Client, error) {
- client := newClient(tags)
- return client, client.SetDSN(dsn)
-}
-
-// NewClient constructs a Sentry client and spawns a background goroutine to
-// handle packets sent by Client.Report.
-//
-// Deprecated: use New and NewWithTags instead
-func NewClient(dsn string, tags map[string]string) (*Client, error) {
- client := newClient(tags)
- return client, client.SetDSN(dsn)
-}
-
-// Client encapsulates a connection to a Sentry server. It must be initialized
-// by calling NewClient. Modification of fields concurrently with Send or after
-// calling Report for the first time is not thread-safe.
-type Client struct {
- Tags map[string]string
-
- Transport Transport
-
- // DropHandler is called when a packet is dropped because the buffer is full.
- DropHandler func(*Packet)
-
- // Context that will get appending to all packets
- context *context
-
- mu sync.RWMutex
- url string
- projectID string
- authHeader string
- release string
- environment string
- sampleRate float32
-
- // default logger name (leave empty for 'root')
- defaultLoggerName string
-
- includePaths []string
- ignoreErrorsRegexp *regexp.Regexp
- queue chan *outgoingPacket
-
- // A WaitGroup to keep track of all currently in-progress captures
- // This is intended to be used with Client.Wait() to assure that
- // all messages have been transported before exiting the process.
- wg sync.WaitGroup
-
- // A Once to track only starting up the background worker once
- start sync.Once
-}
-
-// Initialize a default *Client instance
-var DefaultClient = newClient(nil)
-
-func (c *Client) SetIgnoreErrors(errs []string) error {
- joinedRegexp := strings.Join(errs, "|")
- r, err := regexp.Compile(joinedRegexp)
- if err != nil {
- return fmt.Errorf("failed to compile regexp %q for %q: %v", joinedRegexp, errs, err)
- }
-
- c.mu.Lock()
- c.ignoreErrorsRegexp = r
- c.mu.Unlock()
- return nil
-}
-
-func (c *Client) shouldExcludeErr(errStr string) bool {
- c.mu.RLock()
- defer c.mu.RUnlock()
- return c.ignoreErrorsRegexp != nil && c.ignoreErrorsRegexp.MatchString(errStr)
-}
-
-func SetIgnoreErrors(errs ...string) error {
- return DefaultClient.SetIgnoreErrors(errs)
-}
-
-// SetDSN updates a client with a new DSN. It safe to call after and
-// concurrently with calls to Report and Send.
-func (client *Client) SetDSN(dsn string) error {
- if dsn == "" {
- return nil
- }
-
- client.mu.Lock()
- defer client.mu.Unlock()
-
- uri, err := url.Parse(dsn)
- if err != nil {
- return err
- }
-
- if uri.User == nil {
- return ErrMissingUser
- }
- publicKey := uri.User.Username()
- secretKey, hasSecretKey := uri.User.Password()
- uri.User = nil
-
- if idx := strings.LastIndex(uri.Path, "/"); idx != -1 {
- client.projectID = uri.Path[idx+1:]
- uri.Path = uri.Path[:idx+1] + "api/" + client.projectID + "/store/"
- }
- if client.projectID == "" {
- return ErrMissingProjectID
- }
-
- client.url = uri.String()
-
- if hasSecretKey {
- client.authHeader = fmt.Sprintf("Sentry sentry_version=4, sentry_key=%s, sentry_secret=%s", publicKey, secretKey)
- } else {
- client.authHeader = fmt.Sprintf("Sentry sentry_version=4, sentry_key=%s", publicKey)
- }
-
- return nil
-}
-
-// Sets the DSN for the default *Client instance
-func SetDSN(dsn string) error { return DefaultClient.SetDSN(dsn) }
-
-// SetRelease sets the "release" tag.
-func (client *Client) SetRelease(release string) {
- client.mu.Lock()
- defer client.mu.Unlock()
- client.release = release
-}
-
-// SetEnvironment sets the "environment" tag.
-func (client *Client) SetEnvironment(environment string) {
- client.mu.Lock()
- defer client.mu.Unlock()
- client.environment = environment
-}
-
-// SetDefaultLoggerName sets the default logger name.
-func (client *Client) SetDefaultLoggerName(name string) {
- client.mu.Lock()
- defer client.mu.Unlock()
- client.defaultLoggerName = name
-}
-
-// SetSampleRate sets how much sampling we want on client side
-func (client *Client) SetSampleRate(rate float32) error {
- client.mu.Lock()
- defer client.mu.Unlock()
-
- if rate < 0 || rate > 1 {
- return ErrInvalidSampleRate
- }
- client.sampleRate = rate
- return nil
-}
-
-// SetRelease sets the "release" tag on the default *Client
-func SetRelease(release string) { DefaultClient.SetRelease(release) }
-
-// SetEnvironment sets the "environment" tag on the default *Client
-func SetEnvironment(environment string) { DefaultClient.SetEnvironment(environment) }
-
-// SetDefaultLoggerName sets the "defaultLoggerName" on the default *Client
-func SetDefaultLoggerName(name string) {
- DefaultClient.SetDefaultLoggerName(name)
-}
-
-// SetSampleRate sets the "sample rate" on the degault *Client
-func SetSampleRate(rate float32) error { return DefaultClient.SetSampleRate(rate) }
-
-func (client *Client) worker() {
- for outgoingPacket := range client.queue {
-
- client.mu.RLock()
- url, authHeader := client.url, client.authHeader
- client.mu.RUnlock()
-
- outgoingPacket.ch <- client.Transport.Send(url, authHeader, outgoingPacket.packet)
- client.wg.Done()
- }
-}
-
-// Capture asynchronously delivers a packet to the Sentry server. It is a no-op
-// when client is nil. A channel is provided if it is important to check for a
-// send's success.
-func (client *Client) Capture(packet *Packet, captureTags map[string]string) (eventID string, ch chan error) {
- ch = make(chan error, 1)
-
- if client == nil {
- // return a chan that always returns nil when the caller receives from it
- close(ch)
- return
- }
-
- if client.sampleRate < 1.0 && mrand.Float32() > client.sampleRate {
- return
- }
-
- if packet == nil {
- close(ch)
- return
- }
-
- if client.shouldExcludeErr(packet.Message) {
- return
- }
-
- // Keep track of all running Captures so that we can wait for them all to finish
- // *Must* call client.wg.Done() on any path that indicates that an event was
- // finished being acted upon, whether success or failure
- client.wg.Add(1)
-
- // Merge capture tags and client tags
- packet.AddTags(captureTags)
- packet.AddTags(client.Tags)
-
- // Initialize any required packet fields
- client.mu.RLock()
- packet.AddTags(client.context.tags)
- projectID := client.projectID
- release := client.release
- environment := client.environment
- defaultLoggerName := client.defaultLoggerName
- client.mu.RUnlock()
-
- // set the global logger name on the packet if we must
- if packet.Logger == "" && defaultLoggerName != "" {
- packet.Logger = defaultLoggerName
- }
-
- err := packet.Init(projectID)
- if err != nil {
- ch <- err
- client.wg.Done()
- return
- }
-
- if packet.Release == "" {
- packet.Release = release
- }
-
- if packet.Environment == "" {
- packet.Environment = environment
- }
-
- outgoingPacket := &outgoingPacket{packet, ch}
-
- // Lazily start background worker until we
- // do our first write into the queue.
- client.start.Do(func() {
- go client.worker()
- })
-
- select {
- case client.queue <- outgoingPacket:
- default:
- // Send would block, drop the packet
- if client.DropHandler != nil {
- client.DropHandler(packet)
- }
- ch <- ErrPacketDropped
- client.wg.Done()
- }
-
- return packet.EventID, ch
-}
-
-// Capture asynchronously delivers a packet to the Sentry server with the default *Client.
-// It is a no-op when client is nil. A channel is provided if it is important to check for a
-// send's success.
-func Capture(packet *Packet, captureTags map[string]string) (eventID string, ch chan error) {
- return DefaultClient.Capture(packet, captureTags)
-}
-
-// CaptureMessage formats and delivers a string message to the Sentry server.
-func (client *Client) CaptureMessage(message string, tags map[string]string, interfaces ...Interface) string {
- if client == nil {
- return ""
- }
-
- if client.shouldExcludeErr(message) {
- return ""
- }
-
- packet := NewPacket(message, append(append(interfaces, client.context.interfaces()...), &Message{message, nil})...)
- eventID, _ := client.Capture(packet, tags)
-
- return eventID
-}
-
-// CaptureMessage formats and delivers a string message to the Sentry server with the default *Client
-func CaptureMessage(message string, tags map[string]string, interfaces ...Interface) string {
- return DefaultClient.CaptureMessage(message, tags, interfaces...)
-}
-
-// CaptureMessageAndWait is identical to CaptureMessage except it blocks and waits for the message to be sent.
-func (client *Client) CaptureMessageAndWait(message string, tags map[string]string, interfaces ...Interface) string {
- if client == nil {
- return ""
- }
-
- if client.shouldExcludeErr(message) {
- return ""
- }
-
- packet := NewPacket(message, append(append(interfaces, client.context.interfaces()...), &Message{message, nil})...)
- eventID, ch := client.Capture(packet, tags)
- if eventID != "" {
- <-ch
- }
-
- return eventID
-}
-
-// CaptureMessageAndWait is identical to CaptureMessage except it blocks and waits for the message to be sent.
-func CaptureMessageAndWait(message string, tags map[string]string, interfaces ...Interface) string {
- return DefaultClient.CaptureMessageAndWait(message, tags, interfaces...)
-}
-
-// CaptureErrors formats and delivers an error to the Sentry server.
-// Adds a stacktrace to the packet, excluding the call to this method.
-func (client *Client) CaptureError(err error, tags map[string]string, interfaces ...Interface) string {
- if client == nil {
- return ""
- }
-
- if err == nil {
- return ""
- }
-
- if client.shouldExcludeErr(err.Error()) {
- return ""
- }
-
- extra := extractExtra(err)
- cause := pkgErrors.Cause(err)
-
- packet := NewPacketWithExtra(err.Error(), extra, append(append(interfaces, client.context.interfaces()...), NewException(cause, GetOrNewStacktrace(cause, 1, 3, client.includePaths)))...)
- eventID, _ := client.Capture(packet, tags)
-
- return eventID
-}
-
-// CaptureErrors formats and delivers an error to the Sentry server using the default *Client.
-// Adds a stacktrace to the packet, excluding the call to this method.
-func CaptureError(err error, tags map[string]string, interfaces ...Interface) string {
- return DefaultClient.CaptureError(err, tags, interfaces...)
-}
-
-// CaptureErrorAndWait is identical to CaptureError, except it blocks and assures that the event was sent
-func (client *Client) CaptureErrorAndWait(err error, tags map[string]string, interfaces ...Interface) string {
- if client == nil {
- return ""
- }
-
- if client.shouldExcludeErr(err.Error()) {
- return ""
- }
-
- extra := extractExtra(err)
- cause := pkgErrors.Cause(err)
-
- packet := NewPacketWithExtra(err.Error(), extra, append(append(interfaces, client.context.interfaces()...), NewException(cause, GetOrNewStacktrace(cause, 1, 3, client.includePaths)))...)
- eventID, ch := client.Capture(packet, tags)
- if eventID != "" {
- <-ch
- }
-
- return eventID
-}
-
-// CaptureErrorAndWait is identical to CaptureError, except it blocks and assures that the event was sent
-func CaptureErrorAndWait(err error, tags map[string]string, interfaces ...Interface) string {
- return DefaultClient.CaptureErrorAndWait(err, tags, interfaces...)
-}
-
-// CapturePanic calls f and then recovers and reports a panic to the Sentry server if it occurs.
-// If an error is captured, both the error and the reported Sentry error ID are returned.
-func (client *Client) CapturePanic(f func(), tags map[string]string, interfaces ...Interface) (err interface{}, errorID string) {
- // Note: This doesn't need to check for client, because we still want to go through the defer/recover path
- // Down the line, Capture will be noop'd, so while this does a _tiny_ bit of overhead constructing the
- // *Packet just to be thrown away, this should not be the normal case. Could be refactored to
- // be completely noop though if we cared.
- defer func() {
- var packet *Packet
- err = recover()
- switch rval := err.(type) {
- case nil:
- return
- case error:
- if client.shouldExcludeErr(rval.Error()) {
- return
- }
- packet = NewPacket(rval.Error(), append(append(interfaces, client.context.interfaces()...), NewException(rval, NewStacktrace(2, 3, client.includePaths)))...)
- default:
- rvalStr := fmt.Sprint(rval)
- if client.shouldExcludeErr(rvalStr) {
- return
- }
- packet = NewPacket(rvalStr, append(append(interfaces, client.context.interfaces()...), NewException(errors.New(rvalStr), NewStacktrace(2, 3, client.includePaths)))...)
- }
-
- errorID, _ = client.Capture(packet, tags)
- }()
-
- f()
- return
-}
-
-// CapturePanic calls f and then recovers and reports a panic to the Sentry server if it occurs.
-// If an error is captured, both the error and the reported Sentry error ID are returned.
-func CapturePanic(f func(), tags map[string]string, interfaces ...Interface) (interface{}, string) {
- return DefaultClient.CapturePanic(f, tags, interfaces...)
-}
-
-// CapturePanicAndWait is identical to CaptureError, except it blocks and assures that the event was sent
-func (client *Client) CapturePanicAndWait(f func(), tags map[string]string, interfaces ...Interface) (err interface{}, errorID string) {
- // Note: This doesn't need to check for client, because we still want to go through the defer/recover path
- // Down the line, Capture will be noop'd, so while this does a _tiny_ bit of overhead constructing the
- // *Packet just to be thrown away, this should not be the normal case. Could be refactored to
- // be completely noop though if we cared.
- defer func() {
- var packet *Packet
- err = recover()
- switch rval := err.(type) {
- case nil:
- return
- case error:
- if client.shouldExcludeErr(rval.Error()) {
- return
- }
- packet = NewPacket(rval.Error(), append(append(interfaces, client.context.interfaces()...), NewException(rval, NewStacktrace(2, 3, client.includePaths)))...)
- default:
- rvalStr := fmt.Sprint(rval)
- if client.shouldExcludeErr(rvalStr) {
- return
- }
- packet = NewPacket(rvalStr, append(append(interfaces, client.context.interfaces()...), NewException(errors.New(rvalStr), NewStacktrace(2, 3, client.includePaths)))...)
- }
-
- var ch chan error
- errorID, ch = client.Capture(packet, tags)
- if errorID != "" {
- <-ch
- }
- }()
-
- f()
- return
-}
-
-// CapturePanicAndWait is identical to CaptureError, except it blocks and assures that the event was sent
-func CapturePanicAndWait(f func(), tags map[string]string, interfaces ...Interface) (interface{}, string) {
- return DefaultClient.CapturePanicAndWait(f, tags, interfaces...)
-}
-
-func (client *Client) Close() {
- close(client.queue)
-}
-
-func Close() { DefaultClient.Close() }
-
-// Wait blocks and waits for all events to finish being sent to Sentry server
-func (client *Client) Wait() {
- client.wg.Wait()
-}
-
-// Wait blocks and waits for all events to finish being sent to Sentry server
-func Wait() { DefaultClient.Wait() }
-
-func (client *Client) URL() string {
- client.mu.RLock()
- defer client.mu.RUnlock()
-
- return client.url
-}
-
-func URL() string { return DefaultClient.URL() }
-
-func (client *Client) ProjectID() string {
- client.mu.RLock()
- defer client.mu.RUnlock()
-
- return client.projectID
-}
-
-func ProjectID() string { return DefaultClient.ProjectID() }
-
-func (client *Client) Release() string {
- client.mu.RLock()
- defer client.mu.RUnlock()
-
- return client.release
-}
-
-func Release() string { return DefaultClient.Release() }
-
-func IncludePaths() []string { return DefaultClient.IncludePaths() }
-
-func (client *Client) IncludePaths() []string {
- client.mu.RLock()
- defer client.mu.RUnlock()
-
- return client.includePaths
-}
-
-func SetIncludePaths(p []string) { DefaultClient.SetIncludePaths(p) }
-
-func (client *Client) SetIncludePaths(p []string) {
- client.mu.Lock()
- defer client.mu.Unlock()
-
- client.includePaths = p
-}
-
-func (c *Client) SetUserContext(u *User) {
- c.mu.Lock()
- defer c.mu.Unlock()
- c.context.setUser(u)
-}
-
-func (c *Client) SetHttpContext(h *Http) {
- c.mu.Lock()
- defer c.mu.Unlock()
- c.context.setHttp(h)
-}
-
-func (c *Client) SetTagsContext(t map[string]string) {
- c.mu.Lock()
- defer c.mu.Unlock()
- c.context.setTags(t)
-}
-
-func (c *Client) ClearContext() {
- c.mu.Lock()
- defer c.mu.Unlock()
- c.context.clear()
-}
-
-func SetUserContext(u *User) { DefaultClient.SetUserContext(u) }
-func SetHttpContext(h *Http) { DefaultClient.SetHttpContext(h) }
-func SetTagsContext(t map[string]string) { DefaultClient.SetTagsContext(t) }
-func ClearContext() { DefaultClient.ClearContext() }
-
-// HTTPTransport is the default transport, delivering packets to Sentry via the
-// HTTP API.
-type HTTPTransport struct {
- *http.Client
-}
-
-func (t *HTTPTransport) Send(url, authHeader string, packet *Packet) error {
- if url == "" {
- return nil
- }
-
- body, contentType, err := serializedPacket(packet)
- if err != nil {
- return fmt.Errorf("error serializing packet: %v", err)
- }
- req, err := http.NewRequest("POST", url, body)
- if err != nil {
- return fmt.Errorf("can't create new request: %v", err)
- }
- req.Header.Set("X-Sentry-Auth", authHeader)
- req.Header.Set("User-Agent", userAgent)
- req.Header.Set("Content-Type", contentType)
- res, err := t.Do(req)
- if err != nil {
- return err
- }
- io.Copy(ioutil.Discard, res.Body)
- res.Body.Close()
- if res.StatusCode != 200 {
- return fmt.Errorf("raven: got http status %d - x-sentry-error: %s", res.StatusCode, res.Header.Get("X-Sentry-Error"))
- }
- return nil
-}
-
-func serializedPacket(packet *Packet) (io.Reader, string, error) {
- packetJSON, err := packet.JSON()
- if err != nil {
- return nil, "", fmt.Errorf("error marshaling packet %+v to JSON: %v", packet, err)
- }
-
- // Only deflate/base64 the packet if it is bigger than 1KB, as there is
- // overhead.
- if len(packetJSON) > 1000 {
- buf := &bytes.Buffer{}
- b64 := base64.NewEncoder(base64.StdEncoding, buf)
- deflate, _ := zlib.NewWriterLevel(b64, zlib.BestCompression)
- deflate.Write(packetJSON)
- deflate.Close()
- b64.Close()
- return buf, "application/octet-stream", nil
- }
- return bytes.NewReader(packetJSON), "application/json", nil
-}
-
-var hostname string
-
-func init() {
- hostname, _ = os.Hostname()
-}