Monitor Your Application with the Winter Boot Actuator
The Actuator exposes operational information about your running application over HTTP, with no controller code: registered beans, configuration properties, environment variables, scheduled tasks, request mappings, Prometheus metrics, and the health of your dependencies. Load balancers, orchestrators, and monitoring agents can use these JSON endpoints to check on the service.
Configuration
Section titled “Configuration”All Actuator endpoints are disabled by default. Turn on the global switch, then enable each endpoint you want in application.yml. Each endpoint can also be mounted at a custom path.
management: endpoints: enabled: true # global switch — must be true for any endpoint to work endpoint: beans: enabled: true path: "manage/beans" configprops: enabled: true path: "manage/configprops" env: enabled: true path: "manage/env" health: enabled: true path: "manage/health" info: enabled: true path: "manage/info" mappings: enabled: true path: "manage/mappings" scheduledtasks: enabled: true path: "manage/scheduledtasks" prometheus: enabled: true path: "manage/prometheus" heapdump: enabled: true path: "manage/heapdump"Available Endpoints
Section titled “Available Endpoints”| Endpoint | Default path | Description |
|---|---|---|
beans |
/beans |
Lists all beans registered in the application context. |
configprops |
/configprops |
Displays all application.yml properties (secret-looking values masked). |
env |
/env |
Exposes environment variables (secret-looking values masked). |
health |
/health |
Aggregated health status from all #[HealthInformer] beans. Answers HTTP 503 when the status is DOWN or OUT_OF_SERVICE, otherwise 200. |
info |
/info |
Application information contributed by #[InfoInformer] beans. |
mappings |
/mappings |
Lists all registered HTTP route mappings. |
scheduledtasks |
/scheduledtasks |
Shows all tasks registered with the #[Scheduled] attribute. |
prometheus |
/prometheus |
Prometheus metrics, including http_request_duration labeled by route template (e.g. /users/{id}) and method, recorded from each worker’s first request. |
heapdump |
/heapdump |
Lists the server’s processes (master, workers, task processes) with PID and memory details. |
Each endpoint is served at its default path unless you set path. The example above moves them all under manage/.
Querying an Endpoint
Section titled “Querying an Endpoint”Once an endpoint is enabled and the application is running, query it with a standard HTTP request:
curl http://localhost:8080/manage/health
curl http://localhost:8080/manage/infoCustom Health Checks with HealthIndicator
Section titled “Custom Health Checks with HealthIndicator”The health endpoint combines the status reported by every class that implements HealthIndicator and is annotated with #[HealthInformer]. Add one for each dependency you care about: databases, message brokers, external APIs, and so on.
Implement the health(): Health method and return one of the Health factory methods for the appropriate state:
| Method | Description |
|---|---|
Health::up() |
Service is healthy and available. |
Health::down(?Throwable $ex = null) |
Service is unavailable. Pass a Throwable to have the exception class and message added as the error detail. |
Health::outOfService() |
Service is intentionally taken out of service (e.g. maintenance). |
Health::unknown() |
Health state cannot be determined. |
Health::status(string $statusCode) |
Custom status code for non-standard states. |
use dev\winterframework\actuator\HealthIndicator;use dev\winterframework\actuator\Health;use dev\winterframework\actuator\stereotype\HealthInformer;use dev\winterframework\stereotype\Autowired;use dev\winterframework\pdbc\PdbcTemplate;
#[HealthInformer]class DatabaseHealthIndicator implements HealthIndicator{ #[Autowired] private PdbcTemplate $pdbc;
public function health(): Health { try { $this->pdbc->queryForScalar('SELECT 1'); return Health::up(); } catch (\Throwable $ex) { return Health::down($ex)->withDetail('database', 'connection check failed'); } }}The response status follows the aggregated health, so load balancers, Kubernetes probes and Docker HEALTHCHECKs that read only the status code see an unhealthy instance: DOWN and OUT_OF_SERVICE answer 503 Service Unavailable, UP and UNKNOWN answer 200 OK. The JSON body is the same in both cases.
Custom Application Info with InfoContributor
Section titled “Custom Application Info with InfoContributor”The info endpoint is populated by beans that implement InfoContributor and are annotated with #[InfoInformer]. Use it to surface metadata such as the application name, version, build timestamp, or Git revision.
Implement the contribute(InfoBuilder $info): void method and call $info->withDetail(key, value) for each piece of information you want to expose. The method is chainable.
use dev\winterframework\actuator\InfoContributor;use dev\winterframework\actuator\InfoBuilder;use dev\winterframework\actuator\stereotype\InfoInformer;
#[InfoInformer]class ApplicationInfoContributor implements InfoContributor{ public function contribute(InfoBuilder $info): void { $info->withDetail('appName', 'ExampleMicroService') ->withDetail('appVersion', '1.0.0-1') ->withDetail('buildTimestamp', '2024-01-15T10:30:00Z'); }}Querying the info endpoint returns a JSON object that merges all contributors:
curl http://localhost:8080/manage/info# {"appName":"ExampleMicroService","appVersion":"1.0.0-1","buildTimestamp":"2024-01-15T10:30:00Z"}