fxsentry

package
v0.0.0-...-a8769a9 Latest Latest
Warning

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

Go to latest
Published: Apr 27, 2026 License: Apache-2.0 Imports: 10 Imported by: 3

README

Sentry Module

This module provides sentry support.

Components

The module adds support for sentry in two ways:

  • It configures the zap logger to emit sentries on DPanic and Panic. The error is mapped to the sentry exception. The stacktrace is from the place where DPanic is invoked (go errors do not contain stacktraces) Any additional structured data on the log is added as "extra" data to the sentry
  • It makes a *sentry.Client available to manually create sentries. This can be useful if more control over the shape of the sentry is required than what the zap integration provides. Because the client is not created when no DSN is given, any component requiring a *sentry.Client must annotate it as optional in fx, and do the necessary nil checks. See the included example for details.

Configuration

The module provides the following configuration options:

  • Dsn: The sentry DSN. The module is disabled when it is ""
  • Environment: The value of the environment field in the generated sentries. Defaults to production
  • Debug: Determines whether the sentry client emits debug logs.
  • Process: The value of the process tag of the generated events. Will default to the current binary filename if not set.

Documentation

Overview

Example
package main

import (
	"fmt"
	"time"

	sconfig "github.com/exoscale/stelling/config"
	"github.com/exoscale/stelling/fxlogging"
	"github.com/exoscale/stelling/fxsentry"
	sentry "github.com/getsentry/sentry-go"
	"go.uber.org/fx"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

type Config struct {
	fxlogging.Logging
	fxsentry.Sentry
}

func main() {
	conf := &Config{}
	args := []string{"sentry-test", "--logging.mode", "production"}
	if err := sconfig.Load(conf, args); err != nil {
		panic(err)
	}
	app := fx.New(fx.Options(
		fxlogging.NewModule(conf),
		fxsentry.NewModule(conf),
		// zapOpts contains options to make the logs determistic so we can test the output
		fx.Supply(fx.Annotate(zapOpts, fx.ResultTags(`group:"zap_opts,flatten"`))),
		fx.Invoke(testDPanic),
		fx.Invoke(fx.Annotate(testClient, fx.ParamTags(`optional:"true"`))),
		fx.Invoke(shutdown),
	))

	app.Run()

}

func testDPanic(logger *zap.Logger) {
	// Panics when log-mode is development, emits a sentry when sentry.dsn != ""
	// The error will be captured as the exception in sentry
	// Any other structured data is captured as "extra"
	// The stacktrace will be of the position where DPanic is called (because errors do not contain stacktrace information)
	logger.DPanic("Example sentry", zap.Error(fmt.Errorf("test error")), zap.String("extra-data", "some-value"))
}

func testClient(client *sentry.Client) {
	// This is the advanced usage: it is expected that most applications
	// will only need the zap.DPanic integration which is fully transparent
	event := sentry.NewEvent()
	event.Message = "My sentry"
	event.Timestamp = time.Now()
	event.Level = sentry.LevelInfo
	client.CaptureEvent(event, nil, nil)
}

func shutdown(sd fx.Shutdowner) {
	sd.Shutdown() //nolint:errcheck
}

var zapOpts = []zap.Option{
	zap.WithCaller(false),
	zap.WithClock(&fixedClock{ts: 1257894000}),
	zap.AddStacktrace(zapcore.PanicLevel), // Disabling stacktraces to keep things reproducible
}

type fixedClock struct {
	ts int64
}

func (c *fixedClock) Now() time.Time {
	return time.Unix(c.ts, 0).UTC()
}

func (c *fixedClock) NewTicker(d time.Duration) *time.Ticker {
	return time.NewTicker(d)
}
Output:
{"level":"info","ts":"2009-11-10T23:00:00.000Z","msg":"Using configuration","conf":{"Mode":"production","Dsn":"","Environment":"prod","Debug":false,"Process":""}}
{"level":"dpanic","ts":"2009-11-10T23:00:00.000Z","msg":"Example sentry","error":"test error","extra-data":"some-value"}
{"level":"info","ts":"2009-11-10T23:00:00.000Z","msg":"Final configuration","conf":{"Mode":"production","Dsn":"","Environment":"prod","Debug":false,"Process":""}}

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewModule

func NewModule(conf SentryConfig) fx.Option

func NewSentryClient

func NewSentryClient(conf SentryConfig) (*sentry.Client, error)

func ProvideSentryClient

func ProvideSentryClient(lc fx.Lifecycle, conf SentryConfig) (*sentry.Client, error)

func ProvideSentryLogger

func ProvideSentryLogger(logger *zap.Logger, client *sentry.Client) *zap.Logger

Types

type Sentry

type Sentry struct {
	// Dsn contains the sentry Dsn
	// Sentry integration is disabled if this is empty
	Dsn string
	// Environment is reported as the 'environment' tag in any sentry events
	Environment string `default:"prod"`
	// Debug controls whether sentry emits debugs logs about its own actions
	Debug bool
	// Process is the name of the current process, will be reported in the 'process' tag
	// The lib will try to deduce a value from the runtime if not set
	Process string
}

func (*Sentry) MarshalLogObject

func (s *Sentry) MarshalLogObject(enc zapcore.ObjectEncoder) error

func (*Sentry) SentryConfig

func (s *Sentry) SentryConfig() *Sentry

type SentryConfig

type SentryConfig interface {
	SentryConfig() *Sentry
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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