Observability
Observability adds common observability primitives to fusion server.
Observability
Observability stack is composed of these primitives:
-
: it enables to configure your logging using system properties even using GraalVM
native-image
. It is also a good companion for container based deployments (Kubernetes) since you can switch very easily logging to JSON (-Djava.util.logging.manager=io.yupiik.logging.jul.YupiikLogManager -Dio.yupiik.logging.jul.handler.StandardHandler.formatter=json
). -
Healthcheck(s): this is the capacity to test through HTTP the server state, mainly used by Kubernetes to check if the application is ready (can get traffic) and if it is in a broken state (pod should be killed and restarted for ex.). It is part of
fusion-observability
module. -
Metrics: often coupled to prometheus or opentelemetry, it enables to collect metrics (think time series) about your application. It can be technical (CPU usage for ex.) or business (number of downloads, number of open pages by session). It is part of
fusion-observability
module. -
Tracing: this is the ability to trace a business request (a trace) end to end through all the system. Main collectors/UI are Jaegger and Zipkin. Fusion supports that through its
fusion-tracing
module (see HTTP Server or HTTP Client modules).
HTTP Server
By default, observability module adds another web server for observability purposes. Default port is 8181, but you can set fusion.observability.server.port
configuration (system property, environment variable using underscores and uppercasing it) to override it.
The goal to not reuse the same server is to not have to secure this one (it will stay an internal port in your cluster/infrastructure). Since some Kubernetes tooling does not like adding headers to gather the data (prometheus for ex.) it is a good compromise.
Health checks
A health check implements io.yupiik.fusion.observability.health.HealthCheck
API.
Then the observability server will expose a /health
endpoint which will return an HTTP 200 if all health checks are successful and an HTTP 503 if there is at least one failure.
If you need to distinguish between health check types, you can implement type()
method and return something different from live
.
Then you can call the particular endpoints using /health?type=<my type>
. To get the live checks, for example, use /health?type=live
. Without type
query parameter, all checks are executed.
Metrics
Metrics exposes an endpoint /metrics
on observability server which renders the openmetrics stored in io.yupiik.fusion.observability.metrics.MetricsRegistry
.
It supports Gauge
and Counter
metric types.
Here is a common way to use it in your application:
@DefaultScoped
public class MyService {
private final LongAdder myCounter;
public MyService(final MetricsRegistry registry) {
this.myCounter = registry.registerCounter("my-service-counter");
}
public void save(final MyEntity entity) {
// do the normal business code
myCounter.increment();
}
}
TIP
|
you can unregister your counter on the registry if it is a short live counter (to use with a session for example), it will then no more be available but using that with prometheus, you have no guarantee it will be polled, so it can be neat to delay the un-registration until next polling. Gauge can make it easy using |