Back to Feign

README

micrometer/README.md

13.136.1 KB
Original Source

Micrometer

This module integrates Feign with Micrometer so that HTTP calls made through Feign clients are observable through any Micrometer-supported monitoring system (Prometheus, Datadog, CloudWatch, etc.).

Two capabilities are provided:

  • MicrometerCapability — publishes timers, counters and distribution summaries to a MeterRegistry.
  • MicrometerObservationCapability — publishes Micrometer Observations to an ObservationRegistry (which can in turn produce metrics and tracing spans).

Pick one — both record the same underlying call, so registering both would double-count.

Usage

MicrometerCapability

java
GitHub github = Feign.builder()
                     .addCapability(new MicrometerCapability())
                     .target(GitHub.class, "https://api.github.com");

By default, metrics are registered with io.micrometer.core.instrument.Metrics.globalRegistry. Pass your own registry and/or common tags if you want explicit control:

java
MeterRegistry registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);

GitHub github = Feign.builder()
                     .addCapability(new MicrometerCapability(registry, Tags.of("application", "my-app")))
                     .target(GitHub.class, "https://api.github.com");

MicrometerObservationCapability

java
ObservationRegistry observationRegistry = ObservationRegistry.create();

GitHub github = Feign.builder()
                     .addCapability(new MicrometerObservationCapability(observationRegistry))
                     .target(GitHub.class, "https://api.github.com");

To customize the tags or name of the observation, implement FeignObservationConvention (or extend DefaultFeignObservationConvention) and pass it to the constructor:

java
new MicrometerObservationCapability(observationRegistry, new MyFeignObservationConvention());

Metrics published by MicrometerCapability

The capability instruments five stages of a Feign call. Each stage emits a timer; counters and distribution summaries are emitted where noted.

NameTypeDescription
feign.FeignTimerTotal time spent in the Feign method invocation, including encoding, the HTTP call and decoding. Recorded by MeteredInvocationHandleFactory.
feign.Feign.exceptionTimerSame as above, recorded when the invocation throws (any Throwable).
feign.Feign.http_errorCounterIncremented once per FeignException thrown by an invocation. Adds http_status and error_group tags.
feign.ClientTimerTime spent in the underlying HTTP client for a single request. Recorded by MeteredClient.
feign.Client.exceptionTimerSame as above, recorded when the HTTP call throws.
feign.Client.http_response_codeCounterIncremented once per HTTP response (including error responses). Adds http_status, status_group, http_method and uri tags.
feign.AsyncClientTimerAsync-equivalent of feign.Client. Recorded by MeteredAsyncClient.
feign.AsyncClient.exceptionTimerAsync-equivalent of feign.Client.exception.
feign.AsyncClient.http_response_codeCounterAsync-equivalent of feign.Client.http_response_code.
feign.codec.EncoderTimerTime spent encoding the request body. Recorded by MeteredEncoder.
feign.codec.Encoder.response_sizeDistributionSummarySize, in bytes, of the encoded request body. The metric name predates the current behavior.
feign.codec.DecoderTimerTime spent decoding the response body. Recorded by MeteredDecoder.
feign.codec.Decoder.exceptionTimerSame as above, recorded when decoding throws.
feign.codec.Decoder.response_sizeDistributionSummarySize, in bytes, of the response body read by the decoder.

Tags

Every metric carries the following tags, populated by FeignMetricTagResolver:

TagSourceExample
clientTarget interface FQNcom.example.GitHub
methodJava method namecontributors
hostHost extracted from the target URLapi.github.com
exception_nameException simple name (only present on error)FeignException
root_cause_nameRoot cause exception simple name (only present on error)SocketTimeoutException

Additional tags are added by specific metrics:

  • feign.Client.http_response_code / feign.AsyncClient.http_response_code — adds http_status (e.g. 404), status_group (e.g. 4xx), http_method (e.g. GET) and uri (the templated path, e.g. /repos/{owner}/{repo}/contributors).
  • feign.Feign.http_error — adds http_status and error_group (e.g. 5xx).
  • feign.codec.Decoder.* — adds uri.

You can attach extra common tags either through MeterRegistry.config().commonTags(...) or via the MicrometerCapability(MeterRegistry, List<Tag>) / MicrometerCapability(MeterRegistry, Map<String, String>) constructors.

Observation published by MicrometerObservationCapability

A single observation is produced per HTTP call:

NameContextual nameDescription
http.client.requestsHTTP {method} (e.g. HTTP GET)One observation per HTTP request issued by the Feign client. The observation is stopped after the response is received or an exception is signalled.

The default convention (DefaultFeignObservationConvention) attaches the following low-cardinality key values:

KeyValue
http.methodThe HTTP method (GET, POST, ...). UNKNOWN if the request is null.
http.urlThe templated URL of the method.
http.status_codeThe response status code, or CLIENT_ERROR if no response was received.
clientNameThe target interface FQN.

The following key names are also declared on FeignObservationDocumentation and are available for custom conventions to populate: http.scheme, net.peer.host, net.peer.port.

Whatever observation handlers are registered on the ObservationRegistry (for example DefaultMeterObservationHandler for metrics, a tracing handler for spans) decide what is ultimately emitted.