Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation request: rollbar-reactive-streams-reactor example #307

Open
matsev opened this issue Aug 18, 2023 · 5 comments
Open

Documentation request: rollbar-reactive-streams-reactor example #307

matsev opened this issue Aug 18, 2023 · 5 comments
Labels

Comments

@matsev
Copy link

matsev commented Aug 18, 2023

Please add some recommendations and a working example of a rollbar-reactive-streams-reactor to the list of java examples on your docs page. Questions that comes to mind are what happens if you combine the rollbar-reactive-streams-reactor with log appenders such as rollbar-logback or rollbar-log4j2? What happens if you omit the rollbar-reactive-streams-reactor entirely and revert use vanilla Log4J or Logback in the reactive code path, etc?

Can you please also share a more involved example then the one provided in the com.rollbar.reactivestreams.reactor.example.Application which I find somewhat rudimentary.

@ghost
Copy link

ghost commented Aug 18, 2023

@matsev Sure thing. We have some examples, but we'll need to clean them up. If nothing urgent comes up, we'll update the examples by the end of next week.

@matsev
Copy link
Author

matsev commented Aug 21, 2023

One question that has surfaced is if log statements need to be duplicated? For example, if we use ReactorRollbar for error logs, will the error message also be forwarded to standard logging libraries (e.g. Java Util Logging, Commons Logging, Log4J, or SLF4J depending on application)? Maybe it is configurable?

Reason for asking is that without this option, either developer experience will suffer (as each log statement need to be written twice) or operations experience will suffer (if ops need to go back and forth between Rollbar logs and application logs to get the full picture when troubleshooting application errors).

@ghost
Copy link

ghost commented Aug 31, 2023

@matsev I had an internal discussion about your requests. I want to share some updates and ask you to specify specific questions.

Please add some recommendations and a working example of a rollbar-reactive-streams-reactor to the list of java examples on your docs page. Can you please also share a more involved example then the one provided in the com.rollbar.reactivestreams.reactor.example.Application which I find somewhat rudimentary.

Can you elaborate on what you consider a more involved example? We're happy to update the reactor example you mentioned, but we need more hints on what you missed.

Questions that comes to mind are what happens if you combine the rollbar-reactive-streams-reactor with log appenders such as rollbar-logback or rollbar-log4j2?

You can use both, but the log appender must be configured separately, and rollbar-reactive-streams-reactor will not forward any errors to the logger. If you intend to send errors to Rollbar and also write them to the log files, rollbar-log4j2 or rollbar-logback are the best options. Also, it's a good idea to use the async wrappers provided by Log4J or Logback, to ensure logging actions don't block the reactive operators.

What happens if you omit the rollbar-reactive-streams-reactor entirely and revert use vanilla Log4J or Logback in the reactive code path, etc?

This can work. Use the rollbar-logback or rollbar-log4j2 packages, but wrap them in an async appended so they won't block your application. This will not send the full stack trace, but probably the last frame only. Logging in a reactive environment is a fairly complex thing. You might want to check the Debug Mode section in the Reactor Tools documentation for more details.

@matsev
Copy link
Author

matsev commented Sep 12, 2023

It is unclear to me if you recommend that I use an (async) log appender or the ReactorRollbar or both. We will use standard (async) logback appender for our application logs. Given this premise, what value does ReactorRollbar add? Observing that the sample application decorates a failing mono by using onErrorResume(). How is this different from the code below:

public class Application {
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(Application.class);

    // ...

    Mono<HttpClientResponse> request = HttpClient.create()
        .get()
        .uri(url)
        .response()
        .onErrorResume(t -> {
            log.error("bad stuff happened", t);
            return Mono.error(t);
        });
}

I locked in Rollbar's documentation for configuration examples for an async log appender configuration. Maybe I was looking in the wrong place, because I have not found any async log appender example? I found the logback.xml in the reference docs and a corresponding logback.xml in the example repository, but they are both synchronous.

Can you elaborate on what you consider a more involved example?

  • From the looks of it, the logMonoError only permits logging of the raw Throwable. How can one provide a log statement with some additional context (without wrapping the throwable in another throwable)?
  • What would a Spring example look like for the reactive stack (with and without ReactiveRollbar), c.f. Rollbar Spring

@ghost
Copy link

ghost commented Oct 11, 2023

  1. The logging API is not reactive, so you can’t use ReactorRollbar in a log appender in a way that would benefit the application. We cannot get the logging action to become part of the reactive stream as the log.error call does not return a Mono or Flux.
  2. In this context, maybe using the Rollbar appender, wrapped in an async proxy, and not ReactorRollbar, might be the best choice.

As for the async wrapper, it will depend on the underlying logging implementation. If you’re using logback, here’s an example of how to configure it: https://sorenpoulsen.com/set-up-slf4j-with-logbacks-asyncappender

As for the tradeoff, it’s the usual tradeoff in non-blocking, callback-based concurrency vs thread-based concurrency.

Sending occurrences via ReactorRollbar means its HTTP requests will be non-blocking, just like the rest of the user’s reactive workflow. With this approach, the number of in-flight requests is not limited to the number of OS threads that are running, and this applies to the reporting of occurrences to Rollbar as well as any other function in the application.

On the other hand, the async appender offloads the log action to a different thread dedicated to logging. With only 1 thread, there can only be 1 in-flight request to report an occurrence, and it will be blocking (the thread won’t progress until the request is completed.)

Though I wouldn’t call this a tradeoff situation, I think ReactorRollbar will work better in a reactive application, and I can’t think of any significant drawbacks. But it’s impossible to use ReactorRollbar if you want occurrences to be reported via the slf4j API, as that API is not reactive.

@linear linear bot added the React label Apr 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant