mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2025-12-13 17:10:36 +00:00
155 lines
3.4 KiB
Go
155 lines
3.4 KiB
Go
package errortracking
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/getsentry/sentry-go"
|
|
)
|
|
|
|
// SentryProvider implements the Provider interface using Sentry
|
|
type SentryProvider struct {
|
|
hub *sentry.Hub
|
|
}
|
|
|
|
// SentryConfig holds the configuration for Sentry
|
|
type SentryConfig struct {
|
|
DSN string
|
|
Environment string
|
|
Release string
|
|
Debug bool
|
|
SampleRate float64
|
|
TracesSampleRate float64
|
|
}
|
|
|
|
// NewSentryProvider creates a new Sentry provider
|
|
func NewSentryProvider(config SentryConfig) (*SentryProvider, error) {
|
|
err := sentry.Init(sentry.ClientOptions{
|
|
Dsn: config.DSN,
|
|
Environment: config.Environment,
|
|
Release: config.Release,
|
|
Debug: config.Debug,
|
|
AttachStacktrace: true,
|
|
SampleRate: config.SampleRate,
|
|
TracesSampleRate: config.TracesSampleRate,
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to initialize Sentry: %w", err)
|
|
}
|
|
|
|
return &SentryProvider{
|
|
hub: sentry.CurrentHub(),
|
|
}, nil
|
|
}
|
|
|
|
// CaptureError captures an error with the given severity and additional context
|
|
func (s *SentryProvider) CaptureError(ctx context.Context, err error, severity Severity, extra map[string]interface{}) {
|
|
if err == nil {
|
|
return
|
|
}
|
|
|
|
hub := sentry.GetHubFromContext(ctx)
|
|
if hub == nil {
|
|
hub = s.hub
|
|
}
|
|
|
|
event := sentry.NewEvent()
|
|
event.Level = s.convertSeverity(severity)
|
|
event.Message = err.Error()
|
|
event.Exception = []sentry.Exception{
|
|
{
|
|
Value: err.Error(),
|
|
Type: fmt.Sprintf("%T", err),
|
|
Stacktrace: sentry.ExtractStacktrace(err),
|
|
},
|
|
}
|
|
|
|
if extra != nil {
|
|
event.Extra = extra
|
|
}
|
|
|
|
hub.CaptureEvent(event)
|
|
}
|
|
|
|
// CaptureMessage captures a message with the given severity and additional context
|
|
func (s *SentryProvider) CaptureMessage(ctx context.Context, message string, severity Severity, extra map[string]interface{}) {
|
|
if message == "" {
|
|
return
|
|
}
|
|
|
|
hub := sentry.GetHubFromContext(ctx)
|
|
if hub == nil {
|
|
hub = s.hub
|
|
}
|
|
|
|
event := sentry.NewEvent()
|
|
event.Level = s.convertSeverity(severity)
|
|
event.Message = message
|
|
|
|
if extra != nil {
|
|
event.Extra = extra
|
|
}
|
|
|
|
hub.CaptureEvent(event)
|
|
}
|
|
|
|
// CapturePanic captures a panic with stack trace
|
|
func (s *SentryProvider) CapturePanic(ctx context.Context, recovered interface{}, stackTrace []byte, extra map[string]interface{}) {
|
|
if recovered == nil {
|
|
return
|
|
}
|
|
|
|
hub := sentry.GetHubFromContext(ctx)
|
|
if hub == nil {
|
|
hub = s.hub
|
|
}
|
|
|
|
event := sentry.NewEvent()
|
|
event.Level = sentry.LevelError
|
|
event.Message = fmt.Sprintf("Panic: %v", recovered)
|
|
event.Exception = []sentry.Exception{
|
|
{
|
|
Value: fmt.Sprintf("%v", recovered),
|
|
Type: "panic",
|
|
},
|
|
}
|
|
|
|
if extra != nil {
|
|
event.Extra = extra
|
|
}
|
|
|
|
if stackTrace != nil {
|
|
event.Extra["stack_trace"] = string(stackTrace)
|
|
}
|
|
|
|
hub.CaptureEvent(event)
|
|
}
|
|
|
|
// Flush waits for all events to be sent (useful for graceful shutdown)
|
|
func (s *SentryProvider) Flush(timeout int) bool {
|
|
return sentry.Flush(time.Duration(timeout) * time.Second)
|
|
}
|
|
|
|
// Close closes the provider and releases resources
|
|
func (s *SentryProvider) Close() error {
|
|
sentry.Flush(2 * time.Second)
|
|
return nil
|
|
}
|
|
|
|
// convertSeverity converts our Severity to Sentry's Level
|
|
func (s *SentryProvider) convertSeverity(severity Severity) sentry.Level {
|
|
switch severity {
|
|
case SeverityError:
|
|
return sentry.LevelError
|
|
case SeverityWarning:
|
|
return sentry.LevelWarning
|
|
case SeverityInfo:
|
|
return sentry.LevelInfo
|
|
case SeverityDebug:
|
|
return sentry.LevelDebug
|
|
default:
|
|
return sentry.LevelError
|
|
}
|
|
}
|