square / retrofit

A type-safe HTTP client for Android and the JVM

Home Page:https://square.github.io/retrofit/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Micrometer Observation API support

jonatan-ivanov opened this issue · comments

What kind of issue is this?

  • Question. This issue tracker is not the place for questions. If you want to ask how to do
    something, or to understand why something isn't working the way you expect it to, use Stack
    Overflow. https://stackoverflow.com/questions/tagged/retrofit

  • Bug report. If you’ve found a bug, spend the time to write a failing test. Bugs with tests
    get fixed. Here’s an example: https://gist.github.com/swankjesse/6608b4713ad80988cdc9

  • Feature Request. Start by telling us what problem you’re trying to solve. Often a solution
    already exists! Don’t send pull requests to implement new features without first getting our
    support. Sometimes we leave features out on purpose to keep the project small.


I'm a co-maintainer of Spring Cloud Sleuth and Micrometer projects (together with @shakuzen and @marcingrzejszczak).

Micrometer's Observation API is part of the Micrometer 1.10 release and Micrometer Tracing is a new project. The idea of this API is that you instrument code once but you get multiple benefits out of it - e.g. you can get tracing, metrics, logging or whatever you see fit).

We were curious if there's interest in adding Micrometer Observation API support so that automatically (when on classpath) metrics and spans could be created and tracing context propagation could happen too. In other words metrics and tracing for this project could be created + if there are Micrometer Observation compatible projects, then they will join the whole graph (e.g. whole Spring Framework 6, Micronaut, Apache Dubbo, Apache Camel, Resilience4j, RabbitMQ, etc). Via Micrometer Tracing one can use OpenTelemetry or OpenZipkin Brave Tracer, but with the handler mechanism the possibilities are endless :)

If there's interest in adding that feature, we can provide a PR.

To say I'm hesitant about adding a dependency on a third-party monitoring or instrumentation library directly would be an understatement. We generally try to avoid coupling ourselves to such things, even if they purport to be vendor-neutral abstractions.

Retrofit is already fairly dynamic in where you can inject behavior such that you can likely get anything you need. A Call.Factory allows you to wrap an underlying HTTP client. OkHttp's EventListener gives you granular callbacks about what's happening with the underlying connection. A Converter that unconditionally wraps another gives you metrics about serialization and deserialization. A CallAdapter that unconditionally wrap another gives you metrics about the execution mechanism (such as RxJava) that the caller is using to facilitate running the requests.

If there is anything specific that is missing I would entertain adding a generic EventListener similar to OkHttp to provide access to the behaviors going on inside the library. This allows our users to hook into any kind of observability solution they want in a strictly opt-in manner. I also would not want any magic behavior to automatically be enabled solely because the classpath contained some dependency.

Hi Jake,

Thanks for the reply, let me answer your points.

I'm hesitant about adding a dependency on a third-party monitoring or instrumentation library directly [...]

I think it should not be a direct dependency of retrofit (core), I would advise against it for retrofit's case, I would suggest creating a new module for this that can depend on Micrometer (e.g.: retrofit-micrometer) ~somewhat like the current converter/adapter modules do with jackson, guava, gson, etc. This module could use the mechanism you mentioned above but it is completely optional for the users; they don't won't use it unless they explicitly ask for it.

I also would not want any magic behavior to automatically be enabled solely because the classpath contained some dependency.

I should have been more clear on that. That magic behavior would not happen in retrofit itself. Retrofit would just provide the necessary components that would be auto-configured in the frameworks that also support Micrometer (Spring, Quarkus, Micronaut, etc.) in case retrofit-micrometer is on the classpath (this is already happening with other modules).

If this is truly able to be built on the existing abstractions that Retrofit provides, I would prefer to see it prototyped outside the repo (as we've done with https://github.com/JakeWharton/retrofit2-kotlinx-serialization-converter/). I personally don't have much time to dedicate to larger-efforts within this project and certainly not something of this magnitude. This will allow proving that the concept can work (and also publishing that artifact in the interim for end-users to try). Then, once proven to work, and assuming this is something that has decent widespread applicability, we can talk about moving it into the project as a first-party supported thing. But keep in mind the whole design of Retrofit is such that we don't want to own 100% of the integrations and there are plenty of third-party adapters and converters in the wild which we really like.

Since we've already instrumented OkHttp in Micrometer, we've managed to use Retrofit with that instrumentation (example here micrometer-metrics/micrometer#4041) . I guess we can close this issue (our suggestion will be to just use OkHttp instrumentation).

Sounds good. Thanks for following up.