upgrade deps; rewrite smtp session
This commit is contained in:
6
vendor/github.com/archdx/zerolog-sentry/README.md
generated
vendored
6
vendor/github.com/archdx/zerolog-sentry/README.md
generated
vendored
@@ -6,7 +6,6 @@
|
||||
```go
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
stdlog "log"
|
||||
"os"
|
||||
|
||||
@@ -15,14 +14,15 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
w, err := zlogsentry.New("http://e35657dcf4fb4d7c98a1c0b8a9125088@localhost:9000/2")
|
||||
w, err := zlogsentry.New("http://e35657dcf4fb4d7c98a1c0b8a9125088@localhost:9000/2", zlogsentry.WithEnvironment("dev"), zlogsentry.WithRelease("1.0.0"))
|
||||
if err != nil {
|
||||
stdlog.Fatal(err)
|
||||
}
|
||||
|
||||
defer w.Close()
|
||||
|
||||
logger := zerolog.New(io.MultiWriter(w, os.Stdout)).With().Timestamp().Logger()
|
||||
multi := zerolog.MultiLevelWriter(os.Stdout, w)
|
||||
logger := zerolog.New(multi).With().Timestamp().Logger()
|
||||
|
||||
logger.Error().Err(errors.New("dial timeout")).Msg("test message")
|
||||
}
|
||||
|
||||
7
vendor/github.com/archdx/zerolog-sentry/errors.go
generated
vendored
Normal file
7
vendor/github.com/archdx/zerolog-sentry/errors.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
package zlogsentry
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var ErrFlushTimeout = errors.New("zlogsentry flush timeout")
|
||||
281
vendor/github.com/archdx/zerolog-sentry/writer.go
generated
vendored
281
vendor/github.com/archdx/zerolog-sentry/writer.go
generated
vendored
@@ -1,7 +1,10 @@
|
||||
package zlogsentry
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
@@ -27,62 +30,123 @@ var now = time.Now
|
||||
type Writer struct {
|
||||
hub *sentry.Hub
|
||||
|
||||
levels map[zerolog.Level]struct{}
|
||||
flushTimeout time.Duration
|
||||
levels map[zerolog.Level]struct{}
|
||||
flushTimeout time.Duration
|
||||
withBreadcrumbs bool
|
||||
}
|
||||
|
||||
// Write handles zerolog's json and sends events to sentry.
|
||||
func (w *Writer) Write(data []byte) (int, error) {
|
||||
event, ok := w.parseLogEvent(data)
|
||||
if ok {
|
||||
w.hub.CaptureEvent(event)
|
||||
// should flush before os.Exit
|
||||
if event.Level == sentry.LevelFatal {
|
||||
w.hub.Flush(w.flushTimeout)
|
||||
// addBreadcrumb adds event as a breadcrumb
|
||||
func (w *Writer) addBreadcrumb(event *sentry.Event) {
|
||||
if !w.withBreadcrumbs {
|
||||
return
|
||||
}
|
||||
|
||||
// category is totally optional, but it's nice to have
|
||||
var category string
|
||||
if _, ok := event.Extra["category"]; ok {
|
||||
if v, ok := event.Extra["category"].(string); ok {
|
||||
category = v
|
||||
}
|
||||
}
|
||||
|
||||
return len(data), nil
|
||||
w.hub.AddBreadcrumb(&sentry.Breadcrumb{
|
||||
Category: category,
|
||||
Message: event.Message,
|
||||
Level: event.Level,
|
||||
Data: event.Extra,
|
||||
}, nil)
|
||||
}
|
||||
|
||||
// Write handles zerolog's json and sends events to sentry.
|
||||
func (w *Writer) Write(data []byte) (n int, err error) {
|
||||
n = len(data)
|
||||
|
||||
lvl, err := w.parseLogLevel(data)
|
||||
if err != nil {
|
||||
return n, nil
|
||||
}
|
||||
|
||||
event, ok := w.parseLogEvent(data)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
event.Level, ok = levelsMapping[lvl]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if _, enabled := w.levels[lvl]; !enabled {
|
||||
// if the level is not enabled, add event as a breadcrumb
|
||||
w.addBreadcrumb(event)
|
||||
return
|
||||
}
|
||||
|
||||
w.hub.CaptureEvent(event)
|
||||
// should flush before os.Exit
|
||||
if event.Level == sentry.LevelFatal {
|
||||
w.hub.Flush(w.flushTimeout)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// implements zerolog.LevelWriter
|
||||
func (w *Writer) WriteLevel(level zerolog.Level, p []byte) (n int, err error) {
|
||||
n = len(p)
|
||||
|
||||
event, ok := w.parseLogEvent(p)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
event.Level, ok = levelsMapping[level]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if _, enabled := w.levels[level]; !enabled {
|
||||
// if the level is not enabled, add event as a breadcrumb
|
||||
w.addBreadcrumb(event)
|
||||
return
|
||||
}
|
||||
|
||||
w.hub.CaptureEvent(event)
|
||||
// should flush before os.Exit
|
||||
if event.Level == sentry.LevelFatal {
|
||||
w.hub.Flush(w.flushTimeout)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Close forces client to flush all pending events.
|
||||
// Can be useful before application exits.
|
||||
func (w *Writer) Close() error {
|
||||
w.hub.Flush(w.flushTimeout)
|
||||
if ok := w.hub.Flush(w.flushTimeout); !ok {
|
||||
return ErrFlushTimeout
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// parses the log level from the encoded log
|
||||
func (w *Writer) parseLogLevel(data []byte) (zerolog.Level, error) {
|
||||
lvlStr, err := jsonparser.GetUnsafeString(data, zerolog.LevelFieldName)
|
||||
if err != nil {
|
||||
return zerolog.Disabled, nil
|
||||
}
|
||||
|
||||
return zerolog.ParseLevel(lvlStr)
|
||||
}
|
||||
|
||||
// parses the event except the log level
|
||||
func (w *Writer) parseLogEvent(data []byte) (*sentry.Event, bool) {
|
||||
const logger = "zerolog"
|
||||
|
||||
lvlStr, err := jsonparser.GetUnsafeString(data, zerolog.LevelFieldName)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
lvl, err := zerolog.ParseLevel(lvlStr)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
_, enabled := w.levels[lvl]
|
||||
if !enabled {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
sentryLvl, ok := levelsMapping[lvl]
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
event := sentry.Event{
|
||||
Timestamp: now(),
|
||||
Level: sentryLvl,
|
||||
Logger: logger,
|
||||
Extra: map[string]interface{}{},
|
||||
}
|
||||
|
||||
err = jsonparser.ObjectEach(data, func(key, value []byte, vt jsonparser.ValueType, offset int) error {
|
||||
err := jsonparser.ObjectEach(data, func(key, value []byte, vt jsonparser.ValueType, offset int) error {
|
||||
switch string(key) {
|
||||
case zerolog.MessageFieldName:
|
||||
event.Message = bytesToStrUnsafe(value)
|
||||
@@ -98,7 +162,6 @@ func (w *Writer) parseLogEvent(data []byte) (*sentry.Event, bool) {
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
@@ -152,15 +215,27 @@ type optionFunc func(*config)
|
||||
|
||||
func (fn optionFunc) apply(c *config) { fn(c) }
|
||||
|
||||
type EventHintCallback func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event
|
||||
|
||||
type config struct {
|
||||
levels []zerolog.Level
|
||||
sampleRate float64
|
||||
release string
|
||||
environment string
|
||||
serverName string
|
||||
ignoreErrors []string
|
||||
debug bool
|
||||
flushTimeout time.Duration
|
||||
levels []zerolog.Level
|
||||
sampleRate float64
|
||||
release string
|
||||
environment string
|
||||
serverName string
|
||||
ignoreErrors []string
|
||||
breadcrumbs bool
|
||||
debug bool
|
||||
tracing bool
|
||||
debugWriter io.Writer
|
||||
httpClient *http.Client
|
||||
httpProxy string
|
||||
httpsProxy string
|
||||
caCerts *x509.CertPool
|
||||
maxErrorDepth int
|
||||
flushTimeout time.Duration
|
||||
beforeSend sentry.EventProcessor
|
||||
tracesSampleRate float64
|
||||
}
|
||||
|
||||
// WithLevels configures zerolog levels that have to be sent to Sentry.
|
||||
@@ -207,6 +282,13 @@ func WithIgnoreErrors(reList []string) WriterOption {
|
||||
})
|
||||
}
|
||||
|
||||
// WithBreadcrumbs enables sentry client breadcrumbs.
|
||||
func WithBreadcrumbs() WriterOption {
|
||||
return optionFunc(func(cfg *config) {
|
||||
cfg.breadcrumbs = true
|
||||
})
|
||||
}
|
||||
|
||||
// WithDebug enables sentry client debug logs.
|
||||
func WithDebug() WriterOption {
|
||||
return optionFunc(func(cfg *config) {
|
||||
@@ -214,6 +296,69 @@ func WithDebug() WriterOption {
|
||||
})
|
||||
}
|
||||
|
||||
// WithTracing enables sentry client tracing.
|
||||
func WithTracing() WriterOption {
|
||||
return optionFunc(func(cfg *config) {
|
||||
cfg.tracing = true
|
||||
})
|
||||
}
|
||||
|
||||
// WithTracingSampleRate sets tracing sample rate.
|
||||
func WithTracingSampleRate(tsr float64) WriterOption {
|
||||
return optionFunc(func(cfg *config) {
|
||||
cfg.tracesSampleRate = tsr
|
||||
})
|
||||
}
|
||||
|
||||
// WithBeforeSend sets a callback which is called before event is sent.
|
||||
func WithBeforeSend(beforeSend sentry.EventProcessor) WriterOption {
|
||||
return optionFunc(func(cfg *config) {
|
||||
cfg.beforeSend = beforeSend
|
||||
})
|
||||
}
|
||||
|
||||
// WithDebugWriter enables sentry client tracing.
|
||||
func WithDebugWriter(w io.Writer) WriterOption {
|
||||
return optionFunc(func(cfg *config) {
|
||||
cfg.debugWriter = w
|
||||
})
|
||||
}
|
||||
|
||||
// WithHttpClient sets custom http client.
|
||||
func WithHttpClient(httpClient *http.Client) WriterOption {
|
||||
return optionFunc(func(cfg *config) {
|
||||
cfg.httpClient = httpClient
|
||||
})
|
||||
}
|
||||
|
||||
// WithHttpProxy enables sentry client tracing.
|
||||
func WithHttpProxy(proxy string) WriterOption {
|
||||
return optionFunc(func(cfg *config) {
|
||||
cfg.httpProxy = proxy
|
||||
})
|
||||
}
|
||||
|
||||
// WithHttpsProxy enables sentry client tracing.
|
||||
func WithHttpsProxy(proxy string) WriterOption {
|
||||
return optionFunc(func(cfg *config) {
|
||||
cfg.httpsProxy = proxy
|
||||
})
|
||||
}
|
||||
|
||||
// WithCaCerts enables sentry client tracing.
|
||||
func WithCaCerts(caCerts *x509.CertPool) WriterOption {
|
||||
return optionFunc(func(cfg *config) {
|
||||
cfg.caCerts = caCerts
|
||||
})
|
||||
}
|
||||
|
||||
// WithMaxErrorDepth sets the max depth of error chain.
|
||||
func WithMaxErrorDepth(maxErrorDepth int) WriterOption {
|
||||
return optionFunc(func(cfg *config) {
|
||||
cfg.maxErrorDepth = maxErrorDepth
|
||||
})
|
||||
}
|
||||
|
||||
// New creates writer with provided DSN and options.
|
||||
func New(dsn string, opts ...WriterOption) (*Writer, error) {
|
||||
cfg := newDefaultConfig()
|
||||
@@ -222,15 +367,23 @@ func New(dsn string, opts ...WriterOption) (*Writer, error) {
|
||||
}
|
||||
|
||||
err := sentry.Init(sentry.ClientOptions{
|
||||
Dsn: dsn,
|
||||
SampleRate: cfg.sampleRate,
|
||||
Release: cfg.release,
|
||||
Environment: cfg.environment,
|
||||
ServerName: cfg.serverName,
|
||||
IgnoreErrors: cfg.ignoreErrors,
|
||||
Debug: cfg.debug,
|
||||
Dsn: dsn,
|
||||
SampleRate: cfg.sampleRate,
|
||||
Release: cfg.release,
|
||||
Environment: cfg.environment,
|
||||
ServerName: cfg.serverName,
|
||||
IgnoreErrors: cfg.ignoreErrors,
|
||||
Debug: cfg.debug,
|
||||
EnableTracing: cfg.tracing,
|
||||
DebugWriter: cfg.debugWriter,
|
||||
HTTPClient: cfg.httpClient,
|
||||
HTTPProxy: cfg.httpProxy,
|
||||
HTTPSProxy: cfg.httpsProxy,
|
||||
CaCerts: cfg.caCerts,
|
||||
MaxErrorDepth: cfg.maxErrorDepth,
|
||||
BeforeSend: cfg.beforeSend,
|
||||
TracesSampleRate: cfg.tracesSampleRate,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -241,7 +394,31 @@ func New(dsn string, opts ...WriterOption) (*Writer, error) {
|
||||
}
|
||||
|
||||
return &Writer{
|
||||
hub: sentry.CurrentHub(),
|
||||
hub: sentry.CurrentHub(),
|
||||
levels: levels,
|
||||
flushTimeout: cfg.flushTimeout,
|
||||
withBreadcrumbs: cfg.breadcrumbs,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewWithHub creates a writer using an existing sentry Hub and options.
|
||||
func NewWithHub(hub *sentry.Hub, opts ...WriterOption) (*Writer, error) {
|
||||
if hub == nil {
|
||||
return nil, errors.New("hub cannot be nil")
|
||||
}
|
||||
|
||||
cfg := newDefaultConfig()
|
||||
for _, opt := range opts {
|
||||
opt.apply(&cfg)
|
||||
}
|
||||
|
||||
levels := make(map[zerolog.Level]struct{}, len(cfg.levels))
|
||||
for _, lvl := range cfg.levels {
|
||||
levels[lvl] = struct{}{}
|
||||
}
|
||||
|
||||
return &Writer{
|
||||
hub: hub,
|
||||
levels: levels,
|
||||
flushTimeout: cfg.flushTimeout,
|
||||
}, nil
|
||||
|
||||
Reference in New Issue
Block a user