getsentry / sentry-go

The official Go SDK for Sentry (sentry.io)
https://docs.sentry.io/platforms/go/
MIT License
913 stars 212 forks source link

Add ability to add custom stacktraces #253

Open Mokto opened 4 years ago

Mokto commented 4 years ago

Hi,

Summary

Add ability to add custom stacktraces to the ones that sentry-go is finding automatically

Motivation

I'm using github.com/ztrue/tracerr that contains all my traces when anything goes wrong.

I'd like to add that information to Sentry, as a stacktrace. The information is not as accurate as the one from tracerr.

I'm currently pushing it as breadcrumbs, which is definitely not ideal (especially since we can't "clear" breadcrumbs)

Thanks!

PS : it might be out of scope, I might misunderstand something about the plugin. If so, I'm sorry :)

rhcarvalho commented 4 years ago

This is a valid request and something we intend to support.

I have a WIP branch to rework the way how stack traces are extracted and it should make room for extraction from custom error types.

I'm currently pushing it as breadcrumbs, which is definitely not ideal (especially since we can't "clear" breadcrumbs)

@Mokto, doesn't Scope.ClearBreadcrumbs work for you?

Mokto commented 4 years ago

It should work indeed ;) I will try soon.

Thanks!

derekperkins commented 3 years ago

This is important for us. We're capturing stacktraces and annotating them with meta (breadcrumbs) as we move up the stack, but aren't reporting until we get back up to a root level handler. In raven-go, we have a simple conversion function that works great.

// sentryStacktrace converts our stack representation to Sentry's
func (err *Err) sentryStacktrace() *sentry.Stacktrace {
    frames := make([]*sentry.StacktraceFrame, 0, len(err.frames))
    for i := len(err.frames) - 1; i >= 0; i-- {
        f := err.frames[i]
        frames = append(frames, &sentry.StacktraceFrame{
            Filename:     f.file,
            Function:     f.fn,
            Lineno:       f.line,
            AbsolutePath: f.path,
            InApp:        f.class == classApp,
        })
    }
    return &sentry.Stacktrace{
        Frames: frames,
    }
}

What I can't do today is annotate those frames with their "breadcrumb" data, so that would be very nice. At the end of the day, we're wrapping our errors and just want to convert those and send them to Sentry without a ton of SDK magic. Is that in scope for this SDK or should we look at just using the api directly?

derekperkins commented 3 years ago

I found that I can skip all the magic by just assembling the *sentry.Event myself, including the stacktrace, which has a spot for variables without using breadcrumbs. It's working great for us now!

    return &sentry.Event{
        Extra:   err.sentryExtra(),
        Level:   err.sentryLevel(),
        Tags:    err.sentryTags(c),
        Message: msg,
        User: sentry.User{
            ID: strconv.Itoa(ctx.UserID(c)),
        },
        Request: req,
        Exception: []sentry.Exception{{
            Value:      err.rootErr.Error(),
            Stacktrace: err.sentryStacktrace(),
        }},
    }
rhcarvalho commented 3 years ago

Hi @derekperkins!

From your description in https://github.com/getsentry/sentry-go/issues/253#issuecomment-719957140, I wonder if you considered using BeforeSend or an EventProcessor?

BeforeSend let's you mutate error events before they are sent to Sentry and you should have all info there.

pierrre commented 3 years ago

I really would like to see this implemented. I saw https://github.com/getsentry/sentry-go/pull/310 and I understand why it's not suitable.

I can suggest this, add a function:

func RegisterStackTraceExtractor(f func(error) *StackTrace)

It will add the extractor to a slice. When we want to extract, we iterate over the list of extractor. The first non-nil returned stack trace is used.

By default, Sentry could provide extractors for the most popular libraries.

We could iterate the slice in reverse order, so we give more priority to the extractor registered by the users.

WDYT ?

derekperkins commented 3 years ago

@rhcarvalho I just now saw your question. We aren't using Sentry itself to create events, so neither of those options would be useful. We just needed a way to convert our own internal error representation, with associated stacktrace and context vars, to a Stackdriver event, and once I figured out the data model, it worked perfectly, and I submitted a small PR to make it more obvious how the Go fields translate to the Sentry UI https://github.com/getsentry/sentry-go/pull/325

pierrre commented 3 years ago

Hello WDYT about my proposal ? https://github.com/getsentry/sentry-go/issues/253#issuecomment-785193900

pierrre commented 2 years ago

Hello ! I would like to be able to use the stack traces from my own error library https://github.com/pierrre/errors Currently in sentry-go it's not possible to easily extract the stack traces from an unsupported third party error library.

I have several options:

Here is why I think the 3rd option is not doable:

Here's what I'm planning to do:

WDYT ?

github-actions[bot] commented 1 year ago

This issue has gone three weeks without activity. In another week, I will close it.

But! If you comment or otherwise update it, I will reset the clock, and if you label it Status: Backlog or Status: In Progress, I will leave it alone ... forever!


"A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀

pierrre commented 1 year ago

not fixed

the-jackalope commented 1 year ago

Bumping this to ask whether Sentry would consider exporting an interface we could wrap errors in that records Stacktrace at the source of the error, much like Rollbar's Go SDK does?

I saw a TODO comment in stacktrace.go to this effect but it seems like nobody got around to it. Happy to take a pass!

cleptric commented 1 year ago

PRs welcome 🙂