OkHttpClient Instrumentation

Micrometer supports OkHttp Client instrumentation through Observation and metrics.

OkHttpClient Observation

Below you can find an example of how to instrument OkHttp Client with Micrometer Observation. That means that depending on your Observation Handler configuration you instrument once, and can have multiple benefits out of it (e.g. metrics, distributed tracing).

// Setting up instrumentation
private OkHttpClient client = new OkHttpClient.Builder().addInterceptor(defaultInterceptorBuilder().build())
    .build();

private OkHttpObservationInterceptor.Builder defaultInterceptorBuilder() {
    return OkHttpObservationInterceptor.builder(observationRegistry, "okhttp.requests")
        .tags(KeyValues.of("foo", "bar"))
        .uriMapper(URI_MAPPER);
}

// Usage example
Request request = new Request.Builder().url(server.baseUrl()).build();

makeACall(client, request);

assertThat(registry.get("okhttp.requests")
    .tags("foo", "bar", "status", "200", "uri", URI_EXAMPLE_VALUE, "target.host", "localhost", "target.port",
            String.valueOf(server.port()), "target.scheme", "http")
    .timer()
    .count()).isEqualTo(1L);
assertThat(testHandler.context).isNotNull();
assertThat(testHandler.context.getAllKeyValues()).contains(KeyValue.of("foo", "bar"),
        KeyValue.of("status", "200"));

The builder allows to change the default ObservationConvention as follows.

// Setting up instrumentation with custom convention
MyConvention myConvention = new MyConvention();
client = new OkHttpClient.Builder()
    .addInterceptor(defaultInterceptorBuilder()
        .observationConvention(new StandardizedOkHttpObservationConvention(myConvention))
        .build())
    .build();

OkHttpClient Metrics

Micrometer supports binding metrics to OkHttpClient through EventListener.

You can collect metrics from OkHttpClient by adding OkHttpMetricsEventListener, as follows:

OkHttpClient client = new OkHttpClient.Builder()
    .eventListener(OkHttpMetricsEventListener.builder(registry, "okhttp.requests")
        .tags(Tags.of("foo", "bar"))
        .build())
    .build();
The uri tag is usually limited to URI patterns to mitigate tag cardinality explosion, but OkHttpClient does not provide URI patterns. We provide URI_PATTERN header to support uri tag, or you can configure a URI mapper to provide your own tag values for uri tag.

To configure a URI mapper, you can use uriMapper(), as follows:

OkHttpClient client = new OkHttpClient.Builder()
    .eventListener(OkHttpMetricsEventListener.builder(registry, "okhttp.requests")
        .uriMapper(req -> req.url().encodedPath())
        .tags(Tags.of("foo", "bar"))
        .build())
    .build();
The sample might trigger tag cardinality explosion, as a URI path itself is being used for tag values.