diff --git a/docs/mp/guides/health.adoc b/docs/mp/guides/health.adoc
index cb5739ea38b..a806d52bc93 100644
--- a/docs/mp/guides/health.adoc
+++ b/docs/mp/guides/health.adoc
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////
- Copyright (c) 2019, 2022 Oracle and/or its affiliates.
+ Copyright (c) 2019, 2023 Oracle and/or its affiliates.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -51,8 +51,7 @@ mvn -U archetype:generate -DinteractiveMode=false \
=== Using the Built-In Health Checks
-Helidon has a set of built-in health checks that are automatically enabled to report various
-health check statuses that are commonly used:
+Helidon has a set of built-in health checks:
* deadlock detection
* available disk space
@@ -61,10 +60,14 @@ health check statuses that are commonly used:
The following example will demonstrate how to use the built-in health checks. These examples are all executed
from the root directory of your project (helidon-quickstart-mp).
+[source,xml]
+.Include dependency for the built-in health checks
+include::{rootdir}/mp/health.adoc[tag=built-in-health-checks-depc]
+
[source,bash]
-.Build the application, skipping unit tests, then run it:
+.Build the application then run it:
----
-mvn package -DskipTests=true
+mvn package
java -jar target/helidon-quickstart-mp.jar
----
@@ -488,9 +491,9 @@ The example below will change the root path.
.Create a file named `application.yaml` in the `resources` directory with the following contents:
----
health:
- web-context: "myhealth" // <1>
+ endpoint: "/myhealth" // <1>
----
-<1> The web-context specifies a new root path for the health endpoint.
+<1> The `endpoint` settings specifies the root path for the health endpoint.
[source,bash]
.Build and run the application, then verify that the health endpoint is using the new `/myhealth` root:
@@ -507,20 +510,21 @@ The following example will change the root path and the health port.
.Update application.yaml to use a different port and root path for the health endpoint:
----
server:
- port: 8080 // <1>
- host: "localhost"
+ port: 8080 // <1>
sockets:
- health: // <2>
- port: 8081 // <3>
- bind-address: "localhost"
+ - name: "admin" // <2>
+ port: 8081 // <3>
+ features:
+ observe:
+ sockets: "admin" // <4>
health:
- routing: "health" // <4>
- web-context: "myhealth"
+ endpoint: "/myhealth" // <5>
+
----
<1> The default port for the application.
-<2> The name of the new socket, it can be any name, this example uses `health`.
-<3> The port for the new health socket.
-<4> The health endpoint routing uses the new socket `health`.
+<2> The name of the new socket, it can be any name, this example uses `admin`.
+<3> The port for the `admin` socket.
+<4> The health endpoint, as part of Helidon's observability support, uses the socket `admin`.
[source,bash]
diff --git a/docs/mp/health.adoc b/docs/mp/health.adoc
index 892f302f607..353ac8dbefc 100644
--- a/docs/mp/health.adoc
+++ b/docs/mp/health.adoc
@@ -79,6 +79,7 @@ If full control over the dependencies is required, and you want to minimize the
To enable built-in health checks add the following dependency
(or use the xref:introduction/microprofile.adoc[helidon-microprofile bundle] )
+//tag::built-in-health-checks-depc[]
[source,xml]
----
@@ -86,7 +87,7 @@ To enable built-in health checks add the following dependency
helidon-health-checks
----
-
+//end::built-in-health-checks-depc[]
== Usage
@@ -154,7 +155,7 @@ The class responsible for configuration is:
include::{rootdir}/config/io_helidon_webserver_observe_health_HealthObserver.adoc[leveloffset=+1,tag=config]
-Current properties may be set in `application.yaml` or in `microprofile-config.properties` with `health` prefix.
+Properties may be set in `application.yaml` or in `microprofile-config.properties`, in both cases using the `health` prefix.
For example, you can specify a custom port and root context for the root health endpoint path.
However, you cannot use different ports, such as http://localhost:8080/myhealth and http://localhost:8081/myhealth/live.
@@ -163,18 +164,18 @@ The example below will change the root path.
[source,properties]
.Create a file named `microprofile-config.properties` in the `resources/META-INF` directory with the following contents:
----
-health.web-context=myhealth #<1>
+health.endpoint=/myhealth #<1>
----
-<1> The web-context specifies a new root path for the health endpoint.
+<1> The `endpoint` setting specifies the root path for the health endpoint.
== Examples
-Generate Helidon MP Quickstart project following these xref:guides/quickstart.adoc[Instruction]
+Generate Helidon MP Quickstart project following these xref:guides/quickstart.adoc[instructions].
=== Using the Built-In Health Checks
-Helidon has a set of built-in health checks that are enabled to report various
-health check statuses that are commonly used:
+Helidon has a set of built-in health checks that can report various
+conditions:
* deadlock detection
* available disk space
@@ -183,6 +184,10 @@ health check statuses that are commonly used:
The following example will demonstrate how to use the built-in health checks. These examples are all executed
from the root directory of your project (helidon-quickstart-mp).
+[source,xml]
+.Include the built-in health checks dependency in your `pom.xml`:
+include::{rootdir}/mp/health.adoc[tag=built-in-health-checks-depc]
+
[source,bash]
.Build the application, then run it:
----
@@ -282,9 +287,6 @@ curl http://localhost:8080/health/live
}
----
-Full example code is available link:{helidon-github-tree-url}/examples/microprofile[here].
-
-
=== Custom Readiness Health Checks
You can add a readiness check to indicate that the application is ready to be used. In this
diff --git a/docs/se/guides/health.adoc b/docs/se/guides/health.adoc
index 1d3b763855e..869d42f4169 100644
--- a/docs/se/guides/health.adoc
+++ b/docs/se/guides/health.adoc
@@ -51,8 +51,7 @@ mvn -U archetype:generate -DinteractiveMode=false \
=== Using the Built-In Health Checks
-Helidon has a set of built-in health checks that can be optionally enabled to report various
- health check statuses that are commonly used:
+Helidon has a set of built-in health checks:
* deadlock detection
* available disk space
@@ -70,391 +69,199 @@ from the root directory of your project (helidon-quickstart-se).
----
+Handling health checks is part of Helidon's observability support.
+By default, when you add the dependency for the built-in health checks, Helidon automatically registers the built-in checks.
+But the generated project explicitly suppresses the build-in health checks, thereby highlighting the custom health checks it adds.
+
+[source,java]
+.Excerpt from `Main.main`:
+----
+ObserveFeature observe = ObserveFeature.builder()
+ .config(config.get("server.features.observe")) // <1>
+ .addObserver(HealthObserver.builder() // <2>
+ .details(true) // <3>
+ .useSystemServices(false) // <4>
+ .addCheck(() -> HealthCheckResponse.builder() // <5>
+ .status(HealthCheckResponse.Status.UP)
+ .detail("time", System.currentTimeMillis())
+ .build(), HealthCheckType.READINESS)
+ .addCheck(() -> HealthCheckResponse.builder() // <6>
+ .status(isStarted())
+ .detail("time", System.currentTimeMillis())
+ .build(), HealthCheckType.STARTUP)
+ .build()) // <7>
+ .build();
+
+----
+<1> Finds and applies configuration for observability.
+<2> Begins preparing the `HealthObserver` according to this app's specific needs.
+<3> Turns on detailed output in HTTP responses to the health endpoint.
+<4> Suppresses automatic registration of built-in health checks.
+<5> Adds a custom readiness health check which always reports `UP`'.
+<6> Adds a custom start-up health check.
+<7> Builds the `HealthObserver` for addition to the `ObserveFeature`.
+
+To see the built-in health checks, temporarily change `useSystemServices` to `true`:
[source,java]
-.Have a look at `Main.java`, and the `createRouting` method:
+.Temporarily enable all built-in health checks
----
-private static Routing createRouting(Config config) {
-
- HealthSupport health = HealthSupport.builder()
- .add(HealthChecks.healthChecks()) // <1>
- .build();
-
- return Routing.builder()
- .register(health) // <2>
- .build();
-}
+ .useSystemServices(true)
----
-<1> Add built-in health checks (requires the `helidon-health-checks`
- dependency).
-<2> Register the created health support with web server routing (adds the
-`/health` endpoint).
-
[source,bash]
-.Build the application, skipping unit tests, then run it:
+.Build the application then run it:
----
-mvn package -DskipTests=true
+mvn package
java -jar target/helidon-quickstart-se.jar
----
[source,bash]
.Verify the health endpoint in a new terminal window:
----
-curl http://localhost:8080/health
+curl http://localhost:8080/observe/health
----
[source,json]
-.JSON response:
+.Built-in health checks in the JSON response:
----
{
- "status": "UP",
+ "status": "DOWN",
"checks": [
- {
- "name": "deadlock",
- "status": "UP"
- },
+ ...
{
"name": "diskSpace",
"status": "UP",
"data": {
- "free": "319.58 GB",
- "freeBytes": 343144304640,
- "percentFree": "68.63%",
"total": "465.63 GB",
- "totalBytes": 499963174912
+ "percentFree": "15.77%",
+ "totalBytes": 499963174912,
+ "free": "73.42 GB",
+ "freeBytes": 78837497856
}
},
{
"name": "heapMemory",
"status": "UP",
"data": {
- "free": "196.84 MB",
- "freeBytes": 206404016,
- "max": "3.56 GB",
- "maxBytes": 3817865216,
- "percentFree": "98.66%",
- "total": "245.50 MB",
- "totalBytes": 257425408
+ "total": "516.00 MB",
+ "percentFree": "99.81%",
+ "max": "8.00 GB",
+ "totalBytes": 541065216,
+ "maxBytes": 8589934592,
+ "free": "500.80 MB",
+ "freeBytes": 525126760
}
+ },
+ {
+ "name": "deadlock",
+ "status": "UP"
}
]
}
-----
-=== Custom Liveness Health Checks
-
-You can create application specific custom health checks and integrate them with Helidon
-using the `HealthSupport` class, which is a WebServer service that contains
-a collection of registered `HealthCheck` instances. When queried, it invokes the registered
-health check and returns a response with a status code representing the overall
-state of the application.
-
-[source,xml]
-.Notice the custom health checks dependency is already in the project's pom.xml file:
-----
-
- io.helidon.health
- helidon-health
-
----
-[source,java]
-.Replace the `HealthSupport` builder in the `Main.createRouting` method:
-----
-HealthSupport health = HealthSupport.builder()
- .addLiveness(() -> HealthCheckResponse.named("LivenessCheck")
- .up()
- .withData("time", System.currentTimeMillis())
- .build()) // <1>
- .build();
-----
-<1> Add a custom liveness health check. This example returns `UP` and current time.
-[source,bash]
-.Build and run the application, then verify the custom health endpoint:
-----
-curl http://localhost:8080/health
-----
+=== Adding Custom Health Checks
-[source,json]
-.JSON response:
-----
-{
- "status": "UP",
- "checks": [
- {
- "name": "LivenessCheck",
- "status": "UP",
- "data": {
- "time": 1546958376613
- }
- }
- ]
-}
-----
+As illustrated above, the generated `Main` class in the QuickStart project adds two custom health checks.
+Your own checks typically assess the conditions in and around your application and report whether the service should be considered started, live, and/or ready.
-=== Custom Readiness Health Checks
+As a trivial but illustrative example, the custom start-up health check in the generated `Main` class reports that the app is _not_ started until eight seconds after the server has started. After that, the start-up check reports that the app _is_ started.
-You can add readiness checks to indicate that the application is ready to be used. In this
-example, the server will wait five seconds before it becomes ready.
+To see this start-up check in action, stop your running server (press ^C), then rerun it.
-[source,java]
-.Add a `readyTime` variable to the `Main` class, then set it five seconds after the application starts:
+[source,bash]
+.Stop the application:
----
-import java.util.concurrent.atomic.AtomicLong; // <1>
-
-public final class Main {
-
- private static AtomicLong readyTime = new AtomicLong(0); // <2>
-
- static WebServer startServer() throws IOException {
-
- server.start();
-
- // Server threads are not daemon. No need to block. Just react.
- try {
- Thread.sleep(5000); // <3>
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
-
- readyTime.set(System.currentTimeMillis()); // <4>
- return server;
+^C
----
-<1> Import AtomicLong.
-<2> Declare the `readyTime` variable.
-<3> Sleep five seconds.
-<4> Set the `readyTime` to the time when the server became ready.
-
-
-[source,java]
-.Add a readiness check to the `HealhSupport` builder in the `Main.createRouting` method:
+and note the output from the server
+[listing]
----
-HealthSupport health = HealthSupport.builder()
- .addLiveness(() -> HealthCheckResponse.named("LivenessCheck")
- .up()
- .withData("time", System.currentTimeMillis())
- .build())
- .addReadiness(() -> HealthCheckResponse.named("ReadinessCheck")
- .status(readyTime.get() != 0 )
- .withData( "time", readyTime.get())
- .build()) // <1>
- .build();
+Shutdown requested by JVM shutting down
+[0x4fdb2ff3] @default socket closed.
+Shutdown finished
----
-<1> Add the readiness check.
-
+then restart the server
[source,bash]
-.Build and run the application. Issue the `curl` command with -v within five seconds and you see the application is not ready:
-----
-curl -v http://localhost:8080/health/ready
-----
-
-[source,json]
-.HTTP response:
----
-...
-< HTTP/1.1 503 Service Unavailable // <1>
-...
-{
- "status": "DOWN",
- "checks": [
- {
- "name": "ReadinessCheck",
- "status": "DOWN",
- "data": {
- "time,": 0
- }
- }
- ]
-}
+java -jar target/helidon-quickstart-se.jar
----
-<1> The HTTP status is `503` since the application is not ready.
-[source,bash]
-.After five seconds you will see the application is ready:
+In another terminal window, within eight seconds access the health endpoint [source,bash]
+.Verify the health endpoint in a new terminal window:
----
-curl -v http://localhost:8080/health/ready
+curl http://localhost:8080/observe/health
----
-
+and notice the output.
[source,json]
-.JSON response:
----
-...
-< HTTP/1.1 200 OK // <1>
-...
{
- "status": "UP",
+ "status": "DOWN", // <1>
"checks": [
{
- "name": "ReadinessCheck",
+ "name": "Main$$Lambda/0x00000001310a8dc8", // <2>
"status": "UP",
"data": {
- "time,": 1566243562097
+ "time": 1697584867358
}
- }
- ]
-}
-----
-<1> The HTTP status is `200` indicating that the application is ready.
-
-=== Custom Startup Health Checks
-
-You can create custom startup health checks to indicate when the application has fully started and, therefore, when the readiness and liveness checks are meaningful.
-
-This example reuses the `readyTime` field added above for the custom readiness check and adds a startup check that waits three additional seconds past the "ready" time before declaring the application started.
-
-[source,java]
-.Add a startup check to the `HealhSupport` builder in the `Main.createRouting` method:
-----
-HealthSupport health = HealthSupport.builder()
- .addLiveness(() -> HealthCheckResponse.named("LivenessCheck")
- .up()
- .withData("time", System.currentTimeMillis())
- .build())
- .addReadiness(() -> HealthCheckResponse.named("ReadinessCheck")
- .status(readyTime.get() != 0 )
- .withData("time", readyTime.get())
- .build())
- .addStartup(() -> HealthCheckResponse.named("StartupCheck") // <1>
- .status(readyTime.get() != 0
- && Duration.ofMillis(System.currentTimeMillis() - readyTime.get()).getSeconds() >= 3)
- .withData("time", readyTime.get())
- .build())
- .build();
-----
-<1> Add the startup check.
-
-[source,bash]
-.Build and run the application. Issue the `curl` command with -v within eight seconds and you see the application is not reported as started:
-----
-curl -v http://localhost:8080/health/started
-----
-
-[source,json]
-.HTTP response:
-----
-...
-< HTTP/1.1 503 Service Unavailable // <1>
-...
-{
- "status": "DOWN",
- "checks": [
+ },
{
- "name": "StartupCheck",
+ "name": "Main$$Lambda/0x00000001310a9a78", // <3>
"status": "DOWN",
"data": {
- "time": 1566243562097
+ "time": 1697584867358
}
- }
- ]
-}
-----
-<1> The HTTP status is `503` since the application is not started.
-
-[source,bash]
-.After eight seconds you will see the application is started:
-----
-curl -v http://localhost:8080/health/started
-----
-
-[source,json]
-.JSON response:
-----
-...
-< HTTP/1.1 200 OK // <1>
+ },
...
-{
- "status": "UP",
- "checks": [
- {
- "name": "StartupCheck",
- "status": "UP",
- "data": {
- "time": 1566243562097
- }
- }
- ]
}
----
-<1> The HTTP status is `200` indicating that the application is started.
-
-
-When using the health check URLs, you can get the following health check data
+<1> Overall health (`DOWN` because at least one check reports `DOWN`).
+<2> The custom readiness check (hard-coded as `UP`).
+<3> The custom start-up check (`DOWN` because the server has not been up for at least eight seconds yet).
-* liveness only - http://localhost:8080/health/live
-* readiness only - http://localhost:8080/health/ready
-* startup only - http://localhost:8080/health/started
-* all - http://localhost:8080/health
-
-
-[source,bash]
-.Get all of liveness, readiness, and startup data from a single query:
-----
-curl http://localhost:8080/health
-----
+Now wait eight seconds and access the endpoint again.
[source,json]
-.JSON response:
----
{
- "status": "UP",
+ "status": "UP", // <1>
"checks": [
{
- "name": "LivenessCheck",
+ "name": "Main$$Lambda/0x00000001310a8dc8",
"status": "UP",
"data": {
- "time": 1566244094548
+ "time": 1697584869478
}
},
{
- "name": "ReadinessCheck",
+ "name": "Main$$Lambda/0x00000001310a9a78", // <2>
"status": "UP",
"data": {
- "time,": 1566244093012
+ "time": 1697584869478
}
},
- {
- "name": "StartupCheck",
- "status": "UP",
- "data": {
- "time": 1566244093012
- }
- }
- ]
+...
}
----
+<1> Overall status (now `UP` because all checks report `UP`).
+<2> The custom start-up check (now `UP` because the server has been up at least eight seconds).
-=== Combine Built-In and Custom Health Checks
+=== Accessing Specific Health Check Types
+You can choose which category of health check to retrieve when you access the health endpoint by adding the health check type as an additional part of the resource path:
-You can combine built-in and custom health checks using the same `HealthSupport` builder.
+* liveness only - http://localhost:8080/observe/health/live
+* readiness only - http://localhost:8080/observe/health/ready
+* startup only - http://localhost:8080/observe/health/started
+* all - http://localhost:8080/observe/health
-[source,java]
-.Register a custom health check in the `Main.createRouting` method:
-----
-HealthSupport health = HealthSupport.builder()
- .add(HealthChecks.healthChecks()) // <1>
- .addLiveness(() -> HealthCheckResponse.named("LivenessCheck")
- .up()
- .withData("time", System.currentTimeMillis())
- .build())
- .addReadiness(() -> HealthCheckResponse.named("ReadinessCheck")
- .status(readyTime.get() != 0)
- .withData("time", readyTime.get())
- .build())
- .addStartup(() -> HealthCheckResponse.named("StartupCheck")
- .status(readyTime.get() != 0
- && Duration.ofMillis(System.currentTimeMillis() - readyTime.get()).getSeconds() >= 3)
- .withData("time", readyTime.get())
- .build())
- .build();
-----
-<1> Add the built-in health checks back to `HealthSupport` builder.
[source,bash]
-.Build and run the application, then verify the health endpoint. You will see both the built-in and custom health check data:
+.Get only start-up health checks
----
-curl http://localhost:8080/health
+curl http://localhost:8080/observe/started
----
[source,json]
@@ -464,100 +271,38 @@ curl http://localhost:8080/health
"status": "UP",
"checks": [
{
- "name": "LivenessCheck",
+ "name": "Main$$Lambda/0x00000001360a9a78",
"status": "UP",
"data": {
- "time": 1566245527673
- }
- },
- {
- "name": "ReadinessCheck",
- "status": "UP",
- "data": {
- "time,": 1566245527620
- },
- {
- "name": "StartupCheck",
- "status": "UP",
- "data": {
- "time,": 1566245527620
- }
- },
- {
- "name": "deadlock",
- "status": "UP"
- },
- {
- "name": "diskSpace",
- "status": "UP",
- "data": {
- "free": "326.17 GB",
- "freeBytes": 350224424960,
- "percentFree": "70.05%",
- "total": "465.63 GB",
- "totalBytes": 499963174912
- }
- },
- {
- "name": "heapMemory",
- "status": "UP",
- "data": {
- "free": "247.76 MB",
- "freeBytes": 259791680,
- "max": "4.00 GB",
- "maxBytes": 4294967296,
- "percentFree": "99.80%",
- "total": "256.00 MB",
- "totalBytes": 268435456
+ "time": 1697585727515
}
}
]
}
----
-
=== Custom Health Check URL Path
-You can use a custom URL path for heath checks by setting the `WebContext`. In the following example, only
-the liveness URL is changed, but you can do the same for the readiness, startup, and default
-health checks.
+You can use a custom URL path for heath checks by setting the `endpoint` for the `HealthObserver`.
[source,java]
-.Register a custom URL path with the custom health check in the `Main.createRouting` method:
+.Set a custom endpoint path:
----
-HealthSupport health = HealthSupport.builder()
- .webContext("/probe/live")// <1>
- .addLiveness(() -> HealthCheckResponse.named("livenessProbe")
- .up()
- .withData("time", System.currentTimeMillis())
- .build())
- .build();
-
+ObserveFeature observe = ObserveFeature.builder()
+ .config(config.get("server.features.observe"))
+ .addObserver(HealthObserver.builder()
+ .endpoint("/myhealth") // <1>
+ .details(true)
+...
----
-<1> Change the liveness URL path using a `WebContext`.
+<1> Changes the health endpoint path to `/myhealth`.
[source,bash]
-.Build and run the application, then verify that the liveness endpoint is using the `/probe/live`:
+.Build and run the application, then verify that the health check endpoint responds at `/myhealth`:
----
-curl http://localhost:8080/probe/live
+curl http://localhost:8080/myhealth
----
-[source,json]
-.JSON response:
-----
-{
- "status": "UP",
- "checks": [
- {
- "name": "livenessProbe",
- "status": "UP",
- "data": {
- "time": 1546958376613
- }
- }
- ]
-}
-----
=== Using Liveness, Readiness, and Startup Health Checks with Kubernetes
@@ -565,29 +310,41 @@ The following example shows how to integrate the Helidon health API in an applic
health endpoints for the Kubernetes liveness, readiness, and startup probes.
[source,java]
-.Change the `HealthSupport` builder in the `Main.createRouting` method to use the built-in liveness checks and custom liveness, readiness, and startup checks:
-----
-HealthSupport health = HealthSupport.builder()
- .add(HealthChecks.healthChecks()) // <1>
- .addLiveness(() -> HealthCheckResponse.named("LivenessCheck") // <2>
- .up()
- .withData("time", System.currentTimeMillis())
- .build())
- .addReadiness(() -> HealthCheckResponse.named("ReadinessCheck") // <3>
- .status(readyTime.get() != 0 )
- .withData("time", readyTime.get())
- .build())
- .addStartup(() -> HealthCheckResponse.named("StartupCheck") // <4>
- .status(readyTime.get() != 0
- && Duration.ofMillis(System.currentTimeMillis() - readyTime.get()).getSeconds() >= 3)
- .withData("time", readyTime.get())
- .build())
- .build();
+.Add a `readyTime` variable to the `Main` class:
+----
+private static AtomicLong readyTime = new AtomicLong(0);
+----
+
+[source,java]
+.Change the `HealthObserver` builder in the `Main.main` method to use new built-in liveness checks and custom liveness, readiness, and startup checks:
+----
+ObserveFeature observe = ObserveFeature.builder()
+ .config(config.get("server.features.observe"))
+ .addObserver(HealthObserver.builder()
+ .useSystemServices(true) // <1>
+ .addCheck(() -> HealthCheckResponse.builder()
+ .status(readyTime.get() != 0)
+ .detail("time", readyTime.get())
+ .build(), HealthCheckType.READINESS) // <2>
+ .addCheck(() -> HealthCheckResponse.builder()
+ .status(readyTime.get() != 0
+ && Duration.ofMillis(System.currentTimeMillis()
+ - readyTime.get())
+ .getSeconds() >= 3)
+ .detail("time", readyTime.get())
+ .build(), HealthCheckType.STARTUP) // <3>
+ .addCheck(() -> HealthCheckResponse.builder()
+ .status(HealthCheckResponse.Status.UP)
+ .detail("time", System.currentTimeMillis())
+ .build(), HealthCheckType.LIVENESS) // <4>
+ .build())
+.build();
+
----
<1> Add built-in health checks.
-<2> Add a custom liveness check.
-<3> Add a custom readiness check.
-<4> Add a custom startup check.
+<2> Add a custom readiness check.
+<3> Add a custom start-up check.
+<4> Add a custom liveness check.
[source,bash]
@@ -711,9 +468,9 @@ kubectl delete -f ./health.yaml
----
=== Summary
-This guide demonstrated how to use health checks in a Helidon SE application as follows:
+This guide demonstrates how to use health checks in a Helidon SE application as follows:
-* Access the default health check
+* Access the default health checks
* Create and use custom readiness, liveness, and startup checks
* Customize the health check root path
* Integrate Helidon health check with Kubernetes
diff --git a/docs/se/health.adoc b/docs/se/health.adoc
index 3b765b463a8..a1ee873b738 100644
--- a/docs/se/health.adoc
+++ b/docs/se/health.adoc
@@ -76,36 +76,51 @@ Optional dependency to use built-in health checks:
----
== API
+To add custom health checks to your application, you need to
+
+* write the code which performs the health checks, and
+* make those custom health checks known to Helidon.
+
+=== Writing Custom Health Checks
A health check is a Java functional interface that returns a
-`HealthCheckResponse` instance. You can choose to implement a health check
-inline with a lambda expression or you can reference a method with the double
-colon operator `::`.
+`HealthCheckResponse` instance. You can create custom health checks in several ways, among them:
+
+* write a class which implements the `HealthCheck` interface,
+* write an in-line lambda expression, or
+* use a method reference a method with the double colon operator `::`.
[source,java]
.Health check with a lambda expression:
----
HealthCheck hc = () -> HealthCheckResponse
- .named("exampleHealthCheck")
- .up()
- .build();
+ .builder()
+ .detail("exampleCheck", "looking-good")
+ .status(HealthCheckResponse.Status.UP) // always "up"
+ .build();
----
[source,java]
-.Health check with method reference:
+.Health check with method reference (in class `Main`):
----
-HealthCheckResponse exampleHealthCheck() {
- return HealthCheckResponse
- .named("exampleHealthCheck")
- .up()
- .build();
-}
-HealthCheck hc = this::exampleHealthCheck;
+static HealthCheckResponse exampleHealthCheck() {
+ return HealthCheckResponse
+ .builder()
+ .detail("exampleHealthCheck", "looking-good")
+ .status(HealthCheckResponse.Status.UP) // always "up"
+ .build();
+ }
+
+HealthCheck hc = Main::exampleHealthCheck;
----
+A real health check would compute its status dynamically based on the conditions in the server rather than hard-coding a fixed value.
+
+=== Adding Custom Health Checks to Helidon
-`HealthSupport` is a WebServer service that contains a collection of
-registered `HealthCheck` instances. When queried, it invokes the registered
-health check and returns a response with a status code representing the overall
+Health support in Helidon is part of Helidon's observability feature.
+`HealthObserver` is a Helidon-provided observability implementation that contains a collection of
+registered `HealthCheck` instances and, when queried, invokes the registered
+health checks and returns a response with a status code representing the overall
status of the application.
[cols="1,5",role="flex, sm7"]
@@ -117,41 +132,34 @@ status of the application.
| `500` | An error occurred while reporting the health.
|=======
-HTTP `GET` responses include JSON content showing the detailed results of all the health checks which the server executed after receiving the request.
-HTTP `HEAD` requests return only the status with no payload.
+You control, either using configuration or adding code to your application, whether the HTTP responses to `GET` requests contain detailed information about each health check.
+With details enabled, HTTP `GET` responses include JSON content showing the detailed results of all the health checks which the server executed after receiving the request.
+With details disabled, HTTP `GET` responses have no payload.
+HTTP `HEAD` requests always return only the status with no payload.
-The following code snippets show how to register health checks while building an
-instance of `HealthSupport`:
+If you add the Helidon health dependency to your `pom.xml` file, Helidon automatically registers the `HelidonObserver` service and responds to the default `/observe/health` endpoint.
+Further, if you add the built-in health checks dependency, Helidon automatically finds them and adds those checks to the `HealthObserver`.
-[source,java]
-.Create the health support service:
-----
-HealthSupport health = HealthSupport.builder()
- .addLiveness(hc) // hc created above
- .build();
-----
+The following example shows how to register your own custom health checks while building and registering an
+instance of `HealthObserver`:
[source,java]
-.Create a custom health check:
+.Create and register the health observer feature with a custom health check
----
-HealthSupport health = HealthSupport.builder()
- .addLiveness(() -> HealthCheckResponse.named("exampleHealthCheck")
- .up()
- .withData("time", System.currentTimeMillis())
- .build())
- .build();
-----
-
-The custom health check above returns a status of `UP` and the current time.
-After creating the `HealthCheck` and registering it in a `HealthSupport`, we
-must add the latter to the WebServer routes as follows:
-
-[source,java]
-----
-Routing.builder()
- .register(health)
- .build();
+WebServer server = WebServer.builder()
+ .config(config.get("server"))
+ .addFeature(ObserveFeature.create(HealthObserver.builder() // <1>
+ .addCheck(hc) // <2>
+ .details(true) // <3>
+ .build())) // <4>
+ .routing(Main::routing)
+ .build()
+ .start();
----
+<1> Create a builder for the `HealthObserver`.
+<2> Add the custom health check to the `HealthObserver.Builder`. Invoke `addCheck` multiple times to add multiple custom health checks.
+<3> Set detailed HTTP response output to `true`.
+<4> Build the `HealthObserver` so it can be added to the observability feature that is registered with the webserver.
Here is a sample response to the custom health check registered above:
@@ -159,16 +167,16 @@ Here is a sample response to the custom health check registered above:
.JSON response:
----
{
- "status": "UP",
- "checks": [
- {
- "name": "exampleHealthCheck",
- "status": "UP",
- "data": {
- "time": 1546958376613
- }
- }
- ]
+ "status": "UP",
+ "checks": [
+ {
+ "name": "Main$$Lambda/0x00000001320ac800",
+ "status": "UP",
+ "data": {
+ "exampleHealthCheck": "looking-good"
+ }
+ },
+...
}
----
@@ -187,7 +195,7 @@ The following table provides a summary of the Health Check API classes.
| Result of a health check invocation that contains a status
| `io.helidon.webserver.observe.health.HealthObserver`
-| WebServer service that exposes `/health` and invokes the registered health
+| WebServer service that exposes `/observe/health` and invokes the registered health
checks
|=======
@@ -223,23 +231,29 @@ common health check statuses:
|`98`
|=======
-The following code adds the default built-in health checks to your application:
+Simply adding the built-in health check dependency is sufficient to register all the built-in health checks automatically.
+If you want to use only some of the built-in checks in your application, you can disable automatic discovery of the built-in health checks and register only the ones you want.
+
+The following code adds only selected built-in health checks to your application:
[source,java]
+.Adding selected built-in health checks
----
-HealthObserver health = HealthObserver.builder()
- .addChecks(HealthChecks.healthChecks()) // <1>
- .build();
-
-Routing.builder()
- .addFeature(ObserveFeature.builder()
- .addObserver(health)) // <2>
- .build();
+WebServer server = WebServer.builder()
+ .config(config.get("server"))
+ .addFeature(ObserveFeature.create(HealthObserver.builder()
+ .useSystemServices(false) // <1>
+ .addCheck(HealthChecks.deadlockCheck()) // <2>
+ .addCheck(hc) // <3>
+ .details(true)
+ .build()))
+ .routing(Main::routing)
+ .build()
+ .start();
----
-<1> Add built-in health checks using defaults (requires the `helidon-health-checks`
-dependency).
-<2> Add the created `HealthObserver` to the `ObserveFeature` registered in the web server routing (adds the
-`/observe/health` endpoint).
+<1> Disables automatic registration of the built-in health checks.
+<2> Adds the specific built-in check(s) you want.
+<3> Adds a custom check.
You can control the thresholds for built-in health checks in either of two ways: