sentry-go icon indicating copy to clipboard operation
sentry-go copied to clipboard

Support logrus out-of-the-box?

Open danqing opened this issue 5 years ago • 13 comments

Logrus is likely the most popular logging library in Go (https://github.com/sirupsen/logrus), with over 10k stars.

Since sentry-go already supports some web frameworks, it will be great if there can be out-of-the-box support for logrus too.

danqing avatar Aug 08 '19 01:08 danqing

Sounds good! Will schedule it for the next sprint :)

kamilogorek avatar Aug 08 '19 10:08 kamilogorek

Why does the sentry go client need support for structured logging? Sorry, maybe I'm missing why this is a useful integration.

logrus is popular because it has been around long, but there are (subjectively speaking) better structured loggers out there.

mfridman avatar Aug 08 '19 15:08 mfridman

Well, I guess for me I already log errors using logrus, and I feel it would be great if they can be automatically picked up by Sentry so I don't need to report them again manually.

It should exist as a logrus hook of some form. fwiw, I've attached what I'm using now here. A problem is I can't have it log my message as the title of the error (when displayed in sentry.io), but may be a good start.

Re. there may be better structured loggers, of course it'd be great if the major ones are all supported, like in the case of web frameworks.

// severityMap is a mapping of logrus log level to sentry log level.
var severityMap = map[log.Level]sentry.Level{
	log.DebugLevel: sentry.LevelDebug,
	log.InfoLevel:  sentry.LevelInfo,
	log.WarnLevel:  sentry.LevelWarning,
	log.ErrorLevel: sentry.LevelError,
	log.FatalLevel: sentry.LevelFatal,
	log.PanicLevel: sentry.LevelFatal,
}

// SentryHook implements logrus.Hook to send errors to sentry.
type SentryHook struct {
	client *sentry.Client
	levels []log.Level
}

// SentryEventIdentityModifier is a sentry event modifier that simply passes
// through the event.
type SentryEventIdentityModifier struct{}

// ApplyToEvent simply returns the event (ignoring the hint).
func (m *SentryEventIdentityModifier) ApplyToEvent(event *sentry.Event, hint *sentry.EventHint) *sentry.Event {
	return event
}

var sentryModifier = &SentryEventIdentityModifier{}

// NewSentryHook creates a sentry hook for logrus given a sentry dsn
func NewSentryHook(dsn, env string) (*SentryHook, error) {
	client, err := sentry.NewClient(sentry.ClientOptions{
		Dsn: dsn, Environment: env,
	})

	if err != nil {
		log.WithField("error", err).Error("Unable to initialize Sentry")
		return nil, err
	}

	return &SentryHook{
		client: client,
		levels: []log.Level{
			log.WarnLevel,
			log.ErrorLevel,
			log.FatalLevel,
			log.PanicLevel,
		},
	}, nil
}

// Levels returns the levels this hook is enabled for. This is a part
// of logrus.Hook.
func (h *SentryHook) Levels() []log.Level {
	return h.levels
}

// Fire is an event handler for logrus. This is a part of logrus.Hook.
func (h *SentryHook) Fire(e *log.Entry) error {
	event := sentry.NewEvent()
	event.Message = e.Message
	event.Level = severityMap[e.Level]
	event.Timestamp = e.Time.Unix()

	var err error
	for k, v := range e.Data {
		if k == log.ErrorKey {
			err = v.(error)
		} else {
			event.Extra[k] = v
		}
	}

	if err != nil {
		stacktrace := sentry.ExtractStacktrace(err)
		event.Exception = []sentry.Exception{{
			Value:      err.Error(),
			Type:       reflect.TypeOf(err).String(),
			Stacktrace: stacktrace,
		}}
	}

	h.client.CaptureEvent(event, nil, sentryModifier)
	return nil
}

danqing avatar Aug 08 '19 15:08 danqing

This is a feature we are also interested in. This would allow us to have the same behavior as with python and the logger integration (https://docs.sentry.io/platforms/python/logging/).

MiLk avatar Nov 11 '19 02:11 MiLk

Type:       reflect.TypeOf(err).String()

@danqing I found that if you change the Type to e.Message, then you will have that as the title of the error

rmartinus avatar Jan 23 '20 00:01 rmartinus

For those who are looking for the solution: https://github.com/makasim/sentryhook

makasim avatar Feb 12 '20 12:02 makasim

Another solution here: https://github.com/onrik/logrus/blob/master/sentry/sentry.go

vesperusiak avatar May 20 '20 05:05 vesperusiak

Here's yet another one, except it doesn't hand craft stack traces and events or use outdated SDKs, it makes sentry-go do all the work.

https://gist.github.com/HakShak/a5a92e21545206cb185dea54cd9974b5

HakShak avatar Sep 04 '20 22:09 HakShak

Sounds good! Will schedule it for the next sprint :)

Has there been any update on this?

albert-csms avatar Feb 17 '21 22:02 albert-csms

Sounds good! Will schedule it for the next sprint :)

Has there been any update on this?

+1

lucifer-wsp avatar Jul 12 '21 08:07 lucifer-wsp

Sounds good! Will schedule it for the next sprint :)

Has there been any update on this?

+1

Any changes?

kuzminT avatar Oct 20 '21 18:10 kuzminT

Any updates?

lcd1232 avatar May 21 '22 10:05 lcd1232

I have a logrus hook I've written, and been using and updating over the last 3 years now at 3 different companies. I'd be delighted to merge it into this repo, if it would be accepted. It may need some updates, as I'm not sure if it handles all general use cases.

https://gitlab.com/flimzy/logrusentry

Would the project maintainers welcome a PR to merge this functionality into this repo? And if so, would you prefer a single top-level function (NewLogrusHook() or similar)? Or a separate sub-package?

flimzy avatar Jul 12 '22 10:07 flimzy