Actuator

Spring Boot includes the Spring Boot Actuator. This section answers questions that often arise from its use.

Change the HTTP Port or Address of the Actuator Endpoints

In a standalone application, the Actuator HTTP port defaults to the same as the main HTTP port. To make the application listen on a different port, set the external property: management.server.port. To listen on a completely different network address (such as when you have an internal network for management and an external one for user applications), you can also set management.server.address to a valid IP address to which the server is able to bind.

For more detail, see the ManagementServerProperties source code and Customizing the Management Server Port in the “Production-Ready Features” section.

Customizing Sanitization

To take control over the sanitization, define a SanitizingFunction bean. The SanitizableData with which the function is called provides access to the key and value as well as the PropertySource from which they came. This allows you to, for example, sanitize every value that comes from a particular property source. Each SanitizingFunction is called in order until a function changes the value of the sanitizable data.

Map Health Indicators to Micrometer Metrics

Spring Boot health indicators return a Status type to indicate the overall system health. If you want to monitor or alert on levels of health for a particular application, you can export these statuses as metrics with Micrometer. By default, the status codes “UP”, “DOWN”, “OUT_OF_SERVICE” and “UNKNOWN” are used by Spring Boot. To export these, you will need to convert these states to some set of numbers so that they can be used with a Micrometer Gauge.

The following example shows one way to write such an exporter:

  • Java

  • Kotlin

import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;

import org.springframework.boot.actuate.health.HealthEndpoint;
import org.springframework.boot.actuate.health.Status;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyHealthMetricsExportConfiguration {

	public MyHealthMetricsExportConfiguration(MeterRegistry registry, HealthEndpoint healthEndpoint) {
		// This example presumes common tags (such as the app) are applied elsewhere
		Gauge.builder("health", healthEndpoint, this::getStatusCode).strongReference(true).register(registry);
	}

	private int getStatusCode(HealthEndpoint health) {
		Status status = health.health().getStatus();
		if (Status.UP.equals(status)) {
			return 3;
		}
		if (Status.OUT_OF_SERVICE.equals(status)) {
			return 2;
		}
		if (Status.DOWN.equals(status)) {
			return 1;
		}
		return 0;
	}

}
import io.micrometer.core.instrument.Gauge
import io.micrometer.core.instrument.MeterRegistry
import org.springframework.boot.actuate.health.HealthEndpoint
import org.springframework.boot.actuate.health.Status
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyHealthMetricsExportConfiguration(registry: MeterRegistry, healthEndpoint: HealthEndpoint) {

	init {
		// This example presumes common tags (such as the app) are applied elsewhere
		Gauge.builder("health", healthEndpoint) { health ->
			getStatusCode(health).toDouble()
		}.strongReference(true).register(registry)
	}

	private fun getStatusCode(health: HealthEndpoint) = when (health.health().status) {
		Status.UP -> 3
		Status.OUT_OF_SERVICE -> 2
		Status.DOWN -> 1
		else -> 0
	}

}