Sentry-java: sentry integration with spring webflux

Created on 16 Nov 2018  路  29Comments  路  Source: getsentry/sentry-java

new spring boot starter module was added in #636. This is relying in spring boot 1.5.x release. My question is how sentry should be configured for apps who do not rely in servlet implementations I mean reactive apps.

Spring enhancement help wanted

Most helpful comment

sentry-core is "finished" from the point of view of Android. Some things would be needed in order to support server side like Sentry.close flushing requests in-flight (although I believe that doesn't work for sentry either) which is needed for serverless scenarios.
But I mean it should be possible to start already integrations on top of sentry-core. When we're close enough to replacing all integrations we have in this repo, we can move that code-base to this repo (having all Java + Android here, as it used to be before Android 2.0)

All 29 comments

I'm guessing you'd need something like this to do Sentry.capture(throwable);?

https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux-exception-handler

However HttpInterface still requires HttpServletRequest in its constructors, so is there anyway to build an HttpInterface or something else with ServerWebExchange?
I tried to copy all the members in HttpInterface and create my own, but it fails when marshaling (no InterfaceBinding provided, and I have no idea about injecting my implementation into SentryClient)

No, we probably need to open up HttpInterface to be constructed in other ways. Like just a full list of the fields or something. PRs are welcome, I probably can't get to it in the short term.

Has WebFlux support been added? I'm seeing a number of thread-bound resources and servlet-specific behaviors in the code (early 2020).

Hey guys! In WebFlux we do it like this:

    @Bean
    fun sentryExceptionHandler(): ErrorWebExceptionHandler {
        // Sentry DSN is taken from SENTRY_DSN environment variable.
        // If it is not defined, a client becomes no-op and does not
        // consume resources.
        val sentryClient = SentryClientFactory.sentryClient()
        sentryClient.release = appVersion

        return ErrorWebExceptionHandler { _, ex ->
            // Message is sent asynchronously using inner thread pool.
            sentryClient.sendException(ex)

            Mono.error(ex)
        }
    }

@weekens I don't think you're capturing the HTTP properties.

@jnfeinstein Yeah, you're right. The first parameter (_) in lambda is actually an HTTP exchange object, all HTTP properties can be taken from there. I just didn't figure out, where to put them in sentryClient.

@bruno-garcia thanks for merging #838 .

@bretthoerner I'll be working on springwebflux integration next because we need this in our projects. If it's possible to have generic-enough support for webflux / project reactor, i'll open another PR with it - would you be interested?

If yes - does your team have any ideas so far regarding webflux support? I've a couple of approaches in my local fork, but i'm not quite happy so far.

hey @pulse00 thanks for your contributions :)

I believe we don't have any work going on for webflux/project reactor.
not sure if @bruno-garcia has something in mind, otherwise PRs are welcome.

would you like to point us to these approaches so we can have a look at it? like a short description or even linking to the classes in your fork would be enough. thanks!

@jnfeinstein Yeah, you're right. The first parameter (_) in lambda is actually an HTTP exchange object, all HTTP properties can be taken from there. I just didn't figure out, where to put them in sentryClient.

just a small workaround would be instead of sending a "throwable", you could build a custom event with all the necessary params and attach the throwable to it and sendEvent
https://github.com/getsentry/sentry-java/blob/master/sentry/src/main/java/io/sentry/SentryClient.java#L126

would you like to point us to these approaches so we can have a look at it? like a short description or even linking to the classes in your fork would be enough. thanks!

sure - will do. would you be open to having a new maven module, something like sentry-spring-webflux ?

@weekens I don't think you're capturing the HTTP properties.

yes, this is indeed the problem. The DefaultSentryClientFactory tries to register a HttpEventBuilderHelper, which will not be registered in a webflux application.

So the sentry issue created by simply calling sentry.sendException contains only the stacktrace, without any http request information, which is sub-optimal.

HttpEventBuilderHelper is incompatible with the webflux stack, since it relies on ThreadLocal to store the current request, which can not be used in a reactive environment, since it does not heave the one thread per request model from the servlet world.

A single http request can be processed on multiple threads in a reactive application. Depending on the reactive pipeline scheduler execution.

My current approach is to try to use the pipelines context as a storage for the ServerWebExchange, and somehow make a custom SpringWebFluxHttpEventBuilder give access to the pipeline context.

This is a bit tricky though, as the sentry client is in fact a singleton, and its builderHelpers would somehow need to subscribe to each http request sequence through a WebFilter or something similar.

sure - will do. would you be open to having a new maven module, something like sentry-spring-webflux ?

It could be that we publish the module as io.sentry but one thing to note is that we plan to release sentry maven package 2.x based on a new API. The API was built as part of the sentry-android project and is currently in a separate repository: https://github.com/getsentry/sentry-android/tree/master/sentry-core

It still requires some work and we haven't had the time to invest in that just yet. So I'm a bit reluctant in making major investments in this repo right now knowing that we'll move all integrations/maven packages to based on the sentry-core package.

@bruno-garcia i agree - as far as i can see the new API looks radically different :) i'd rather not work on spring-webflux in this repo then - does it make sense to look into the new API and try to add an integration there?

@pulse00 If you could contribute on top of that code-base we'd really appreciate. The long term goal is to merge that code here (once all integrations are replaced).

We'd need also a migration step for users. We wrote it for Android developers.

@pulse00 If you could contribute on top of that code-base we'd really appreciate. The long term goal is to merge that code here (once all integrations are replaced).

alright, so just to avoid misundertandings: the longterm goal is to

right?

sentry-core is "finished" from the point of view of Android. Some things would be needed in order to support server side like Sentry.close flushing requests in-flight (although I believe that doesn't work for sentry either) which is needed for serverless scenarios.
But I mean it should be possible to start already integrations on top of sentry-core. When we're close enough to replacing all integrations we have in this repo, we can move that code-base to this repo (having all Java + Android here, as it used to be before Android 2.0)

Hi everyone! Is there any news regarding reactive support (webflux and project reactor )?

3.0.0 was just released so it's a single code base again. We plan to focus on performance support now on top of our current spring integration. Following that we'll consider improving/adding integration and webflux is high on the list there.

Hi, I'm starting to work in a Webflux integration (I need it for one of my projects) that consist in a subclass of AbstractErrorWebExceptionHandler (To capture errors in a webflux application) and a implementation of WebFilter (to associate an hub instance to the current ServerWebExchange and add a Http Breadcrumb with Http request info); This approach is working fine in my project and I'd like to contribute to this repo.
What do you think is the best place to put that code? In the sentry-spring-boot-starter subproject ? or in a new subproject like sentry-spring-webflux? @bruno-garcia @maciejwalkowiak

if this requires to add a new dependency spring-boot-starter-webflux, I'd say we should extract to its own module like sentry-spring-webflux or even sentry-spring-boot-starter-webflux

@marandaneto and I already did a pass on the PR and the direction looks great! @maciejwalkowiak will likely have comments too. Thanks for contributing @dbuos

Hi @marandaneto @dbuos @weekens to use sentry in webflux which dependency should we use ? as

 <dependency>
            <groupId>io.sentry</groupId>
            <artifactId>sentry-spring-boot-starter</artifactId>
</dependency>

doesnot work ?

Hi @marandaneto @dbuos @weekens to use sentry in webflux which dependency should we use ? as

 <dependency>
            <groupId>io.sentry</groupId>
            <artifactId>sentry-spring-boot-starter</artifactId>
</dependency>

doesnot work ?

PR is still open so better you go with Spring or Spring boot

@dbuos wondering if you could pull main into your branch and fix the conflicts, so we finally get back to it as we finished the groundwork for performance and could have more attention to it, thanks :)

Hi @marandaneto Thanks. will it be coming anytime soon ( webflux dependency)? we use webflux so wont be able to Spring boot dependency. any preferable way to achieve this ? logback and log4j i can think of going with.

Hi @marandaneto Thanks. will it be coming anytime soon ( webflux dependency)? we use webflux so wont be able to Spring boot dependency. any preferable way to achieve this ? logback and log4j i can think of going with.

you can use both (logback or log4j) https://docs.sentry.io/platforms/java/
about webflux, it's coming from a contributor, so I can't really give an estimation.

yeah sure, @marandaneto yeah i was trying to do using logback, what i faced environment variables are not getting passed in sentry? so to add any tags like environment tags how do we fetch dynamically ?

yeah sure, @marandaneto yeah i was trying to do using logback, what i faced environment variables are not getting passed in sentry? so to add any tags like environment tags how do we fetch dynamically ?

please follow our docs https://docs.sentry.io/platforms/java/guides/logback you can get this info from there :)
also, open a new issue if you are having trouble setting this up but it's not related to the original issue (webflux).

Was this page helpful?
0 / 5 - 0 ratings