Add HealthContributor and refactor HealthEndpoint

Overhaul `HealthEndpoint` support to make it easier to support health
groups. Prior to this commit the `HealthIndicator` interface was used
for both regular indicators and composite indicators. In addition the
`Health` result was used to both represent individual, system and
composite health. This design unfortunately means that all health
contributors need to be aware of the `HealthAggregator` and could not
easily support heath groups if per-group aggregation is required.

This commit reworks many aspects of the health support in order to
provide a cleaner separation between a `HealthIndicator`and a
composite. The following changes have been made:

- A `HealthContributor` interface has been introduced to represent
  the general concept of something that contributes health information.
  A contributor can either be a `HealthIndicator` or a
  `CompositeHealthContributor`.

- A `HealthComponent` class has been introduced to mirror the
  contributor arrangement. The component can be either
  `CompositeHealth` or `Health`.

- The `HealthAggregator` interface has been replaced with a more
  focused `StatusAggregator` interface which only deals with `Status`
  results.

- `CompositeHealthIndicator` has been replaced with
  `CompositeHealthContributor` which only provides access to other
  contributors. A composite can no longer directly return `Health`.

- `HealthIndicatorRegistry` has been replaced with
  `HealthContributorRegistry` and the default implementation now
  uses a copy-on-write strategy.

- `HealthEndpoint`, `HealthEndpointWebExtension` and
  `ReactiveHealthEndpointWebExtension` now extend a common
  `HealthEndpointSupport` class. They are now driven by a
  health contributor registry and `HealthEndpointSettings`.

- The `HealthStatusHttpMapper` class has been replaced by a
  `HttpCodeStatusMapper` interface.

- The `HealthWebEndpointResponseMapper` class has been replaced
  by a `HealthEndpointSettings` strategy. This allows us to move
  role related logic and `ShowDetails` to the auto-configure module.

- `SimpleHttpCodeStatusMapper` and `SimpleStatusAggregator`
  implementations have been added which are configured via constructor
  arguments rather than setters.

- Endpoint auto-configuration has been reworked and the
  `CompositeHealthIndicatorConfiguration` class has been replaced
  by `CompositeHealthContributorConfiguration`.

- The endpoint JSON has been changed make `details` distinct from
  `components`.

See gh-17926
This commit is contained in:
Phillip Webb
2019-08-20 14:18:27 -07:00
parent 24b5b0d93e
commit 3c535e0de3
143 changed files with 5269 additions and 1303 deletions

View File

@@ -726,17 +726,23 @@ configuration must permit access to the health endpoint for both authenticated a
unauthenticated users.
Health information is collected from the content of a
{sc-spring-boot-actuator}/health/HealthIndicatorRegistry.{sc-ext}[
`HealthIndicatorRegistry`] (by default all
{sc-spring-boot-actuator}/health/HealthIndicator.{sc-ext}[`HealthIndicator`] instances
{sc-spring-boot-actuator}/health/HealthContributorRegistry.{sc-ext}[
`HealthContributorRegistry`] (by default all
{sc-spring-boot-actuator}/health/HealthContributor.{sc-ext}[`HealthContributor`] instances
defined in your `ApplicationContext`. Spring Boot includes a number of auto-configured
`HealthIndicators` and you can also write your own. By default, the final system state is
derived by the `HealthAggregator` which sorts the statuses from each `HealthIndicator`
based on an ordered list of statuses. The first status in the sorted list is used as the
overall health status. If no `HealthIndicator` returns a status that is known to the
`HealthAggregator`, an `UNKNOWN` status is used.
`HealthContributors` and you can also write your own.
TIP: The `HealthIndicatorRegistry` can be used to register and unregister health
A `HealthContributor` can either be a `HealthIndicator` or a `CompositeHealthContributor`.
A `HealthIndicator` provides actual health information, including a `Status`. A
`CompositeHealthContributor` provides a composite of other `HealthContributors`. Taken
together, contributor for a tree structure to represent the overall system heath.
By default, the final system health is derived by a `StatusAggregator` which sorts the
statuses from each `HealthIndicator` based on an ordered list of statuses. The first
status in the sorted list is used as the overall health status. If no `HealthIndicator`
returns a status that is known to the `StatusAggregator`, an `UNKNOWN` status is used.
TIP: The `HealthContributorRegistry` can be used to register and unregister health
indicators at runtime.
@@ -760,7 +766,7 @@ The following `HealthIndicators` are auto-configured by Spring Boot when appropr
|{sc-spring-boot-actuator}/jdbc/DataSourceHealthIndicator.{sc-ext}[`DataSourceHealthIndicator`]
|Checks that a connection to `DataSource` can be obtained.
|{sc-spring-boot-actuator}/elasticsearch/ElasticsearchHealthIndicator.{sc-ext}[`ElasticsearchHealthIndicator`]
|{sc-spring-boot-actuator}/elasticsearch/ElasticSearchRestHealthContributorAutoConfiguration.{sc-ext}[`ElasticSearchRestHealthContributorAutoConfiguration`]
|Checks that an Elasticsearch cluster is up.
|{sc-spring-boot-actuator}/hazelcast/HazelcastHealthIndicator.{sc-ext}[`HazelcastHealthIndicator`]
@@ -833,9 +839,9 @@ In addition to Spring Boot's predefined
{sc-spring-boot-actuator}/health/Status.{sc-ext}[`Status`] types, it is also possible for
`Health` to return a custom `Status` that represents a new system state. In such cases, a
custom implementation of the
{sc-spring-boot-actuator}/health/HealthAggregator.{sc-ext}[`HealthAggregator`] interface
{sc-spring-boot-actuator}/health/StatusAggregator.{sc-ext}[`StatusAggregator`] interface
also needs to be provided, or the default implementation has to be configured by using
the `management.health.status.order` configuration property.
the `management.endpoint.health.status.order` configuration property.
For example, assume a new `Status` with code `FATAL` is being used in one of your
`HealthIndicator` implementations. To configure the severity order, add the following
@@ -843,7 +849,7 @@ property to your application properties:
[source,properties,indent=0]
----
management.health.status.order=FATAL, DOWN, OUT_OF_SERVICE, UNKNOWN, UP
management.endpoint.health.status.order=fatal,down,out-of-service,unknown,up
----
The HTTP status code in the response reflects the overall health status (for example,
@@ -853,10 +859,10 @@ the following property maps `FATAL` to 503 (service unavailable):
[source,properties,indent=0]
----
management.health.status.http-mapping.FATAL=503
management.endpoint.health.status.http-mapping.fatal=503
----
TIP: If you need more control, you can define your own `HealthStatusHttpMapper` bean.
TIP: If you need more control, you can define your own `HttpCodeStatusMapper` bean.
The following table shows the default status mappings for the built-in statuses:
@@ -881,18 +887,18 @@ The following table shows the default status mappings for the built-in statuses:
[[reactive-health-indicators]]
==== Reactive Health Indicators
For reactive applications, such as those using Spring WebFlux, `ReactiveHealthIndicator`
For reactive applications, such as those using Spring WebFlux, `ReactiveHealthContributor`
provides a non-blocking contract for getting application health. Similar to a traditional
`HealthIndicator`, health information is collected from the content of a
{sc-spring-boot-actuator}/health/ReactiveHealthIndicatorRegistry.{sc-ext}[
`ReactiveHealthIndicatorRegistry`] (by default all
{sc-spring-boot-actuator}/health/HealthIndicator.{sc-ext}[`HealthIndicator`] and
{sc-spring-boot-actuator}/health/ReactiveHealthIndicator.{sc-ext}[
`ReactiveHealthIndicator`] instances defined in your `ApplicationContext`. Regular
`HealthIndicator` that do not check against a reactive API are executed on the elastic
`HealthContributor`, health information is collected from the content of a
{sc-spring-boot-actuator}/health/ReactiveHealthContributorRegistry.{sc-ext}[
`ReactiveHealthContributorRegistry`] (by default all
{sc-spring-boot-actuator}/health/HealthContributor.{sc-ext}[`HealthContributor`] and
{sc-spring-boot-actuator}/health/ReactiveHealthContributor.{sc-ext}[
`ReactiveHealthContributor`] instances defined in your `ApplicationContext`). Regular
`HealthContributors` that do not check against a reactive API are executed on the elastic
scheduler.
TIP: In a reactive application, The `ReactiveHealthIndicatorRegistry` can be used to
TIP: In a reactive application, The `ReactiveHealthContributorRegistry` can be used to
register and unregister health indicators at runtime.
To provide custom health information from a reactive API, you can register Spring beans