getsentry / sentry-javascript

Official Sentry SDKs for JavaScript
https://sentry.io
MIT License
7.87k stars 1.55k forks source link

Add support for DigitalOcean and Twilio serverless functions #10810

Open ZacharyDuBois opened 6 months ago

ZacharyDuBois commented 6 months ago

Problem Statement

I want to better the Sentry integration into our Twilio Serverless functions but it seems it does not offer a generic wrapper or a Twilio Serverless or DigitalOcean Serverless wrappers.

Solution Brainstorm

If a generic wrapper for serverless functions could be made, that would probably be the best. These serverless platforms are springing up like wildfire. Twilio specifically could be an awesome integration as they currently give you 0 insight into how your function is preforming or any errors that arise from your functions.

Lms24 commented 6 months ago

Hi @ZacharyDuBois thanks for writing in! At the moment, serverless functions aren't on top of our priorities. However, we do have some wrappers for GCP and AWS lambda functions. You might want to take a look at the source code - maybe you can use them as inspiration to build a wrapper yourself.

If a generic wrapper for serverless functions could be made, that would probably be the best.

I agree, generic is most of the time preferrable; however most serverless function platforms' APIs differ slightly making this quite hard.

If you end up creating a wrapper, feel free to write a guide, publish the wrapper yourself (for those sweet GH stars) or contribute to our repository :) Happy to review!

ZacharyDuBois commented 6 months ago

100% agree with the differing platforms. The main issue with Twilio is the entire process is killed the moment you call the callback function so Sentry never sends any data. What I've ended up doing is moving everything into a new function and wrapping that call with a span then calling flush just prior to the callback. It's been working ok, but some tighter integrations would be nice.

I feel a generic wrapper, if built with enough customization in mind, could actually work well. I'll have to see what I can do. I am still fumbling with Twilio's serverless functions. They aren't very forgiving to anything.

Lms24 commented 6 months ago

yeah, the flushing part is always a problem with serverless functions. I think what you're doing is pretty much in line with how we get around the issue. We just await the flush call with a timeout. Btw, the consequence is that the function might run much longer than without Sentry. Not great but it's the best we can do :(

ZacharyDuBois commented 6 months ago

For anyone that finds this thread, here is my current work around for Twilio Serverless:

exports.handler = async function (context, event, callback) {
    Sentry.init({
        dsn: context.SENTRY_DSN,
        integrations: [new ProfilingIntegration()],

        environment: context.ENVIRONMENT, // Twilio doesn't automatically set this, ensure you have this in your .env
        release: helper.version, // Same with this, ensure you have some level of versioning somewhere. 

        debug: context.SENTRY_DEBUG === 'true', // Twilio's terrible .env parsing.

        sampleRate: parseFloat(context.SENTRY_SAMPLE_RATE),
        tracesSampleRate: parseFloat(context.SENTRY_TRACE_SAMPLE_RATE),
        profilesSampleRate: parseFloat(context.SENTRY_PROFILE_SAMPLE_RATE),
    });

    let response;
    await Sentry.startSpan({
        op: 'invocation', name: '<<PUT SOMETHING HERE>>', attributes: {
            // Misc things here, maybe from the event object.
        },
    }, async () => {
        try {
            response = await actualHandlerFunction(context, event, callback); // Replace this call with where your actual function is.
        } catch (error) {
            console.log(error.message);
            Sentry.captureException(error);
            callback(error);
            return; // Sanity return even though the callback() call will terminate.
        }
    });

    await Sentry.flush(2000);
    callback(null, response);
};

I have been absolutely flooded with work. I will see what I can pull for a Twilio wrapper. DigitalOcean supports more than Node so I will have to look at some other langs for that too.