getsentry / raven-go

Sentry client in Go
https://sentry.io
BSD 3-Clause "New" or "Revised" License
561 stars 148 forks source link

How to use with App Engine? #144

Open josh-burton opened 7 years ago

josh-burton commented 7 years ago

Is it possible to use this with App Engine (standard)?

There would need to be a way to provide a custom transport or use urlfetch.

fruwe commented 7 years ago

@athornz Hello there, I might have the same problem. (Locally errors/messages are reported, but after deploying the errors/messages are not reported)

I am aware, that I might ask something obvious to everyone else, but may I ask what makes App Engine so special, so that it can not send messages to sentry? Isn't reporting a message to sentry just a simple http request?

andwun commented 6 years ago

TLDR: When using App Engine Standard, you have to create your own raven client for each request. See code below.

Today, I ran into this issue, as well. I was using raven.Capture(packet *Packet, captureTags map[string]string) (eventID string, ch chan error) to compile a packet myself. It did what it is supposed to in the dev server. But nothing showed up from inside of GAE.

Taking a look at the error returned via the error channel brought this up:

err = Post https://sentry.io/api/*redacted*/store/: dial tcp: lookup sentry.io on [::1]:53: dial udp [::1]:53: socket: operation not permitted

Now, the issue is clear. The raven package seems to be setting up its own http.Transport. This does not work in App Engine Standard. You have to use the urlfetch service to issue HTTP(s) requests from App Engine Standard.

So you need to create a separate raven client for each request that wants to send something via raven. For this client, you need to swap out the transport like this:

func NewRavenClientForAppEngine(ctx context.Context) (*raven.Client, error) {
    client, err := raven.New(os.Getenv("SENTRY_DSN"))
    if err != nil {
        return nil, err
    }

    client.Transport = &raven.HTTPTransport{
        Client: urlfetch.Client(ctx),
    }

    return client, nil
}

It's not optimal to setup the client for each separate request, I know. It also means you cannot send something to raven without an inbound request (since you don't have an appengine context in this case). But it's simply the same as with any other libraries, like BigQuery or PubSub, to name a few.

royalgiant commented 5 years ago

@andwun do you have an example of your solution? It doesn't seem to be working for me. Logs are still not showing in Sentry for my staging server following what you have there.