zapsentry

package module
v1.11.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 9, 2022 License: MIT Imports: 7 Imported by: 53

README

Sentry client for zap logger

Integration using Sentry DSN

Integration of sentry client into zap.Logger is pretty simple:

func modifyToSentryLogger(log *zap.Logger, DSN string) *zap.Logger {
	cfg := zapsentry.Configuration{
		Level: zapcore.ErrorLevel, //when to send message to sentry
		EnableBreadcrumbs: true, // enable sending breadcrumbs to Sentry 
		BreadcrumbLevel: zapcore.InfoLevel, // at what level should we sent breadcrumbs to sentry
		Tags: map[string]string{
			"component": "system",
		},
	}
	core, err := zapsentry.NewCore(cfg, zapsentry.NewSentryClientFromDSN(DSN))
	
	// to use breadcrumbs feature - create new scope explicitly
	log = log.With(zapsentry.NewScope())
	
	//in case of err it will return noop core. so we can safely attach it
	if err != nil {
		log.Warn("failed to init zap", zap.Error(err))
	}
	return zapsentry.AttachCoreToLogger(core, log)
}

Integraiton using Sentry Client

Integration of sentry client into zap.Logger is pretty simple:

func modifyToSentryLogger(log *zap.Logger, client *sentry.Client) *zap.Logger {
	cfg := zapsentry.Configuration{
		Level: zapcore.ErrorLevel, //when to send message to sentry
		EnableBreadcrumbs: true, // enable sending breadcrumbs to Sentry 
		BreadcrumbLevel: zapcore.InfoLevel, // at what level should we sent breadcrumbs to sentry
		Tags: map[string]string{
			"component": "system",
		},
	}
	core, err := zapsentry.NewCore(cfg, zapsentry.NewSentryClientFromClient(client))
	
	// to use breadcrumbs feature - create new scope explicitly
	log = log.With(zapsentry.NewScope())
	
	//in case of err it will return noop core. so we can safely attach it
	if err != nil {
		log.Warn("failed to init zap", zap.Error(err))
	}
	return zapsentry.AttachCoreToLogger(core, log)
}

Please note that both examples does not guarantee that your events will be sent before the app exists. To ensure this, the easy way is to use the client example and defer the flush. Example:

    sentryClient, err := sentry.NewClient(sentry.ClientOptions{
		Dsn:         "Sentry DSN",
	})
	if err != nil {
		// Handle the error here
	}

	// Flush buffered events before the program terminates.
	// Set the timeout to the maximum duration the program can afford to wait.
	defer sentryClient.Flush(2 * time.Second)

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func AttachCoreToLogger

func AttachCoreToLogger(sentryCore zapcore.Core, l *zap.Logger) *zap.Logger
Example
package main

import (
	"fmt"
	"log"
	"time"

	"github.com/getsentry/sentry-go"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"go.uber.org/zap/zaptest/observer"

	"github.com/TheZeroSlave/zapsentry"
)

func main() {
	// Setup zap with observer (for testing), originally we use
	// 		config = zap.NewDevelopmentConfig()
	//  	logger, err := config.Build()
	// to build zap logger, here we use zap/zaptest/observer for testing
	core, recordedLogs := observer.New(zapcore.DebugLevel)
	logger := zap.New(core, zap.AddStacktrace(zap.DebugLevel))

	// Setup mock sentry client for testing, in general we use sentry.NewClient
	var recordedSentryEvent *sentry.Event
	sentryClient := mockSentryClient(func(event *sentry.Event) {
		recordedSentryEvent = event
	})

	// Setup zapsentry
	core, err := zapsentry.NewCore(zapsentry.Configuration{
		Level:             zapcore.ErrorLevel, // when to send message to sentry
		EnableBreadcrumbs: true,               // enable sending breadcrumbs to Sentry
		BreadcrumbLevel:   zapcore.InfoLevel,  // at what level should we sent breadcrumbs to sentry
		Tags: map[string]string{
			"component": "system",
		},
	}, zapsentry.NewSentryClientFromClient(sentryClient))
	if err != nil {
		log.Fatal(err)
	}
	newLogger := zapsentry.AttachCoreToLogger(core, logger)

	// Send error log
	newLogger.
		With(zapsentry.NewScope()).
		Error("[error] something went wrong!", zap.String("method", "unknown"))

	// Check output
	fmt.Println(recordedLogs.All()[0].Message)
	fmt.Println(recordedSentryEvent.Message)
	fmt.Println(recordedSentryEvent.Extra)
}

func mockSentryClient(f func(event *sentry.Event)) *sentry.Client {
	client, _ := sentry.NewClient(sentry.ClientOptions{
		Dsn:       "",
		Transport: &transport{MockSendEvent: f},
	})
	return client
}

type transport struct {
	MockSendEvent func(event *sentry.Event)
}

// Flush waits until any buffered events are sent to the Sentry server, blocking
// for at most the given timeout. It returns false if the timeout was reached.
func (f *transport) Flush(_ time.Duration) bool { return true }

// Configure is called by the Client itself, providing it it's own ClientOptions.
func (f *transport) Configure(_ sentry.ClientOptions) {}

// SendEvent assembles a new packet out of Event and sends it to remote server.
// We use this method to capture the event for testing
func (f *transport) SendEvent(event *sentry.Event) {
	f.MockSendEvent(event)
}
Output:

[error] something went wrong!
[error] something went wrong!
map[method:unknown]

func NewCore

func NewCore(cfg Configuration, factory SentryClientFactory) (zapcore.Core, error)

func NewScope added in v1.8.0

func NewScope() zapcore.Field

func NewScopeFromScope added in v1.11.0

func NewScopeFromScope(scope *sentry.Scope) zapcore.Field

Types

type ClientGetter added in v1.0.1

type ClientGetter interface {
	GetClient() *sentry.Client
}

type Configuration

type Configuration struct {
	// Tags are passed as is to the corresponding sentry.Event field.
	Tags map[string]string

	// LoggerNameKey is the key for zap logger name.
	// If not empty, the name is added to the rest of zapcore.Field(s),
	// so that be careful with key duplicates.
	// Leave LoggerNameKey empty to disable the feature.
	LoggerNameKey string

	// DisableStacktrace disables adding stacktrace to sentry.Event, if set.
	DisableStacktrace bool

	// Level is the minimal level of sentry.Event(s).
	Level zapcore.Level

	// EnableBreadcrumbs enables use of sentry.Breadcrumb(s).
	// This feature works only when you explicitly passed new scope.
	EnableBreadcrumbs bool

	// BreadcrumbLevel is the minimal level of sentry.Breadcrumb(s).
	// Breadcrumb specifies an application event that occurred before a Sentry event.
	// NewCore fails if BreadcrumbLevel is greater than Level.
	// The field is ignored, if EnableBreadcrumbs is not set.
	BreadcrumbLevel zapcore.Level

	// FlushTimeout is the timeout for flushing events to Sentry.
	FlushTimeout time.Duration

	// Hub overrides the sentry.CurrentHub value.
	// See sentry.Hub docs for more detail.
	Hub *sentry.Hub
}

Configuration is a minimal set of parameters for Sentry integration.

type LevelEnabler added in v1.8.0

type LevelEnabler struct {
	zapcore.Level
	// contains filtered or unexported fields
}

func (*LevelEnabler) Enabled added in v1.8.0

func (l *LevelEnabler) Enabled(lvl zapcore.Level) bool

type SentryClientFactory

type SentryClientFactory func() (*sentry.Client, error)

func NewSentryClientFromClient

func NewSentryClientFromClient(client *sentry.Client) SentryClientFactory

func NewSentryClientFromDSN

func NewSentryClientFromDSN(DSN string) SentryClientFactory

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL