spring-framework/framework-docs/modules/ROOT/pages/integration/observability.adoc

222 lines
12 KiB
Plaintext
Raw Normal View History

2023-04-20 22:03:56 +08:00
[[observability]]
= Observability Support
Micrometer defines an https://micrometer.io/docs/observation[Observation concept that enables both Metrics and Traces] in applications.
2023-07-06 19:27:20 +08:00
Metrics support offers a way to create timers, gauges, or counters for collecting statistics about the runtime behavior of your application.
Metrics can help you to track error rates, usage patterns, performance, and more.
Traces provide a holistic view of an entire system, crossing application boundaries; you can zoom in on particular user requests and follow their entire completion across applications.
Spring Framework instruments various parts of its own codebase to publish observations if an `ObservationRegistry` is configured.
You can learn more about {docs-spring-boot}/html/actuator.html#actuator.metrics[configuring the observability infrastructure in Spring Boot].
2023-04-20 22:03:56 +08:00
[[observability.list]]
== List of produced Observations
Spring Framework instruments various features for observability.
2023-04-19 23:26:17 +08:00
As outlined xref:integration/observability.adoc[at the beginning of this section], observations can generate timer Metrics and/or Traces depending on the configuration.
.Observations produced by Spring Framework
[%autowidth]
|===
|Observation name |Description
2023-04-20 22:03:56 +08:00
|xref:integration/observability.adoc#http-client[`"http.client.requests"`]
|Time spent for HTTP client exchanges
2023-04-20 22:03:56 +08:00
|xref:integration/observability.adoc#http-server[`"http.server.requests"`]
|Processing time for HTTP server exchanges at the Framework level
|===
NOTE: Observations are using Micrometer's official naming convention, but Metrics names will be automatically converted
https://micrometer.io/docs/concepts#_naming_meters[to the format preferred by the monitoring system backend]
(Prometheus, Atlas, Graphite, InfluxDB...).
2023-04-20 22:03:56 +08:00
[[observability.concepts]]
== Micrometer Observation concepts
2023-07-06 19:27:20 +08:00
If you are not familiar with Micrometer Observation, here's a quick summary of the concepts you should know about.
* `Observation` is the actual recording of something happening in your application. This is processed by `ObservationHandler` implementations to produce metrics or traces.
* Each observation has a corresponding `ObservationContext` implementation; this type holds all the relevant information for extracting metadata for it.
2023-07-06 19:27:20 +08:00
In the case of an HTTP server observation, the context implementation could hold the HTTP request, the HTTP response, any exception thrown during processing, and so forth.
* Each `Observation` holds `KeyValues` metadata. In the case of an HTTP server observation, this could be the HTTP request method, the HTTP response status, and so forth.
This metadata is contributed by `ObservationConvention` implementations which should declare the type of `ObservationContext` they support.
2022-12-01 23:14:36 +08:00
* `KeyValues` are said to be "low cardinality" if there is a low, bounded number of possible values for the `KeyValue` tuple (HTTP method is a good example).
Low cardinality values are contributed to metrics only.
2023-07-06 19:27:20 +08:00
Conversely, "high cardinality" values are unbounded (for example, HTTP request URIs) and are only contributed to traces.
* An `ObservationDocumentation` documents all observations in a particular domain, listing the expected key names and their meaning.
2023-04-20 22:03:56 +08:00
[[observability.config]]
== Configuring Observations
Global configuration options are available at the `ObservationRegistry#observationConfig()` level.
Each instrumented component will provide two extension points:
* setting the `ObservationRegistry`; if not set, observations will not be recorded and will be no-ops
* providing a custom `ObservationConvention` to change the default observation name and extracted `KeyValues`
2023-04-20 22:03:56 +08:00
[[observability.config.conventions]]
=== Using custom Observation conventions
Let's take the example of the Spring MVC "http.server.requests" metrics instrumentation with the `ServerHttpObservationFilter`.
2023-07-06 19:27:20 +08:00
This observation uses a `ServerRequestObservationConvention` with a `ServerRequestObservationContext`; custom conventions can be configured on the Servlet filter.
If you would like to customize the metadata produced with the observation, you can extend the `DefaultServerRequestObservationConvention` for your requirements:
2023-04-20 22:03:56 +08:00
include-code::./ExtendedServerRequestObservationConvention[]
2023-07-06 19:27:20 +08:00
If you want full control, you can implement the entire convention contract for the observation you're interested in:
2023-04-20 22:03:56 +08:00
include-code::./CustomServerRequestObservationConvention[]
2023-07-06 19:27:20 +08:00
You can also achieve similar goals using a custom `ObservationFilter` adding or removing key values for an observation.
Filters do not replace the default convention and are used as a post-processing component.
2023-04-20 22:03:56 +08:00
include-code::./ServerRequestObservationFilter[]
You can configure `ObservationFilter` instances on the `ObservationRegistry`.
2023-04-20 22:03:56 +08:00
[[observability.http-server]]
== HTTP Server instrumentation
2023-07-06 19:27:20 +08:00
HTTP server exchange observations are created with the name `"http.server.requests"` for Servlet and Reactive applications.
2023-04-20 22:03:56 +08:00
[[observability.http-server.servlet]]
=== Servlet applications
Applications need to configure the `org.springframework.web.filter.ServerHttpObservationFilter` Servlet filter in their application.
2023-07-06 19:27:20 +08:00
It uses the `org.springframework.http.server.observation.DefaultServerRequestObservationConvention` by default, backed by the `ServerRequestObservationContext`.
2023-07-06 19:27:20 +08:00
This will only record an observation as an error if the `Exception` has not been handled by the web framework and has bubbled up to the Servlet filter.
2023-04-19 23:26:17 +08:00
Typically, all exceptions handled by Spring MVC's `@ExceptionHandler` and xref:web/webmvc/mvc-ann-rest-exceptions.adoc[`ProblemDetail` support] will not be recorded with the observation.
You can, at any point during request processing, set the error field on the `ObservationContext` yourself:
2023-04-20 22:03:56 +08:00
include-code::./UserController[]
NOTE: Because the instrumentation is done at the Servlet Filter level, the observation scope only covers the filters ordered after this one as well as the handling of the request.
2023-07-06 19:27:20 +08:00
Typically, Servlet container error handling is performed at a lower level and won't have any active observation or span.
For this use case, a container-specific implementation is required, such as a `org.apache.catalina.Valve` for Tomcat; this is outside of the scope of this project.
By default, the following `KeyValues` are created:
.Low cardinality Keys
[cols="a,a"]
|===
|Name | Description
|`exception` _(required)_|Name of the exception thrown during the exchange, or `KeyValue#NONE_VALUE`} if no exception happened.
2022-12-01 23:14:36 +08:00
|`method` _(required)_|Name of HTTP request method or `"none"` if the request was not received properly.
|`outcome` _(required)_|Outcome of the HTTP server exchange.
|`status` _(required)_|HTTP response raw status code, or `"UNKNOWN"` if no response was created.
|`uri` _(required)_|URI pattern for the matching handler if available, falling back to `REDIRECTION` for 3xx responses, `NOT_FOUND` for 404 responses, `root` for requests with no path info, and `UNKNOWN` for all other requests.
|===
.High cardinality Keys
[cols="a,a"]
|===
|Name | Description
|`http.url` _(required)_|HTTP request URI.
|===
2023-04-20 22:03:56 +08:00
[[observability.http-server.reactive]]
=== Reactive applications
Applications need to configure the `org.springframework.web.filter.reactive.ServerHttpObservationFilter` reactive `WebFilter` in their application.
2023-07-06 19:27:20 +08:00
It uses the `org.springframework.http.server.reactive.observation.DefaultServerRequestObservationConvention` by default, backed by the `ServerRequestObservationContext`.
2023-07-06 19:27:20 +08:00
This will only record an observation as an error if the `Exception` has not been handled by the web framework and has bubbled up to the `WebFilter`.
2023-04-19 23:26:17 +08:00
Typically, all exceptions handled by Spring WebFlux's `@ExceptionHandler` and xref:web/webflux/ann-rest-exceptions.adoc[`ProblemDetail` support] will not be recorded with the observation.
You can, at any point during request processing, set the error field on the `ObservationContext` yourself:
2023-04-20 22:03:56 +08:00
include-code::./UserController[]
By default, the following `KeyValues` are created:
.Low cardinality Keys
[cols="a,a"]
|===
|Name | Description
2022-12-01 23:14:36 +08:00
|`exception` _(required)_|Name of the exception thrown during the exchange, or `"none"` if no exception happened.
|`method` _(required)_|Name of HTTP request method or `"none"` if the request was not received properly.
|`outcome` _(required)_|Outcome of the HTTP server exchange.
|`status` _(required)_|HTTP response raw status code, or `"UNKNOWN"` if no response was created.
|`uri` _(required)_|URI pattern for the matching handler if available, falling back to `REDIRECTION` for 3xx responses, `NOT_FOUND` for 404 responses, `root` for requests with no path info, and `UNKNOWN` for all other requests.
|===
.High cardinality Keys
[cols="a,a"]
|===
|Name | Description
|`http.url` _(required)_|HTTP request URI.
|===
2023-04-20 22:03:56 +08:00
[[observability.http-client]]
2023-07-06 19:27:20 +08:00
== HTTP Client Instrumentation
2023-07-06 19:27:20 +08:00
HTTP client exchange observations are created with the name `"http.client.requests"` for blocking and reactive clients.
Unlike their server counterparts, the instrumentation is implemented directly in the client so the only required step is to configure an `ObservationRegistry` on the client.
2023-04-20 22:03:56 +08:00
[[observability.http-client.resttemplate]]
=== RestTemplate
Applications must configure an `ObservationRegistry` on `RestTemplate` instances to enable the instrumentation; without that, observations are "no-ops".
Spring Boot will auto-configure `RestTemplateBuilder` beans with the observation registry already set.
2023-07-06 19:27:20 +08:00
Instrumentation uses the `org.springframework.http.client.observation.ClientRequestObservationConvention` by default, backed by the `ClientRequestObservationContext`.
.Low cardinality Keys
[cols="a,a"]
|===
|Name | Description
2022-12-01 23:14:36 +08:00
|`method` _(required)_|Name of HTTP request method or `"none"` if the request could not be created.
|`uri` _(required)_|URI template used for HTTP request, or `"none"` if none was provided. Only the path part of the URI is considered.
|`client.name` _(required)_|Client name derived from the request URI host.
|`status` _(required)_|HTTP response raw status code, or `"IO_ERROR"` in case of `IOException`, or `"CLIENT_ERROR"` if no response was received.
|`outcome` _(required)_|Outcome of the HTTP client exchange.
|`exception` _(required)_|Name of the exception thrown during the exchange, or `"none"` if no exception happened.
|===
.High cardinality Keys
[cols="a,a"]
|===
|Name | Description
|`http.url` _(required)_|HTTP request URI.
|===
2023-04-20 22:03:56 +08:00
[[observability.http-client.webclient]]
=== WebClient
Applications must configure an `ObservationRegistry` on the `WebClient` builder to enable the instrumentation; without that, observations are "no-ops".
Spring Boot will auto-configure `WebClient.Builder` beans with the observation registry already set.
2023-07-06 19:27:20 +08:00
Instrumentation uses the `org.springframework.web.reactive.function.client.ClientRequestObservationConvention` by default, backed by the `ClientRequestObservationContext`.
.Low cardinality Keys
[cols="a,a"]
|===
|Name | Description
2022-12-01 23:14:36 +08:00
|`method` _(required)_|Name of HTTP request method or `"none"` if the request could not be created.
|`uri` _(required)_|URI template used for HTTP request, or `"none"` if none was provided. Only the path part of the URI is considered.
|`client.name` _(required)_|Client name derived from the request URI host.
|`status` _(required)_|HTTP response raw status code, or `"IO_ERROR"` in case of `IOException`, or `"CLIENT_ERROR"` if no response was received.
|`outcome` _(required)_|Outcome of the HTTP client exchange.
|`exception` _(required)_|Name of the exception thrown during the exchange, or `"none"` if no exception happened.
|===
.High cardinality Keys
[cols="a,a"]
|===
|Name | Description
|`http.url` _(required)_|HTTP request URI.
|===