Observability

Observability is the ability to observe the internal state of a running system from the outside. It consists of the three pillars: logging, metrics and traces.

For metrics and traces, Spring Boot uses Micrometer Observation. To create your own observations (which will lead to metrics and traces), you can inject an ObservationRegistry.

import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationRegistry;

import org.springframework.stereotype.Component;

@Component
public class MyCustomObservation {

	private final ObservationRegistry observationRegistry;

	public MyCustomObservation(ObservationRegistry observationRegistry) {
		this.observationRegistry = observationRegistry;
	}

	public void doSomething() {
		Observation.createNotStarted("doSomething", this.observationRegistry)
			.lowCardinalityKeyValue("locale", "en-US")
			.highCardinalityKeyValue("userId", "42")
			.observe(() -> {
				// Execute business logic here
			});
	}

}
Low cardinality tags will be added to metrics and traces, while high cardinality tags will only be added to traces.

Beans of type ObservationPredicate, GlobalObservationConvention, ObservationFilter and ObservationHandler will be automatically registered on the ObservationRegistry. You can additionally register any number of ObservationRegistryCustomizer beans to further configure the registry.

Observability support relies on the Context Propagation library for forwarding the current observation across threads and reactive pipelines. By default, ThreadLocal values are not automatically reinstated in reactive operators. This behavior is controlled with the spring.reactor.context-propagation property, which can be set to auto to enable automatic propagation.

For more details about observations please see the Micrometer Observation documentation.

Observability for JDBC can be configured using a separate project. The Datasource Micrometer project provides a Spring Boot starter which automatically creates observations when JDBC operations are invoked. Read more about it in the reference documentation.
Observability for R2DBC is built into Spring Boot. To enable it, add the io.r2dbc:r2dbc-proxy dependency to your project.

Common Tags

Common tags are generally used for dimensional drill-down on the operating environment, such as host, instance, region, stack, and others. Common tags are applied to all observations as low cardinality tags and can be configured, as the following example shows:

  • Properties

  • YAML

management.observations.key-values.region=us-east-1
management.observations.key-values.stack=prod
management:
  observations:
    key-values:
      region: "us-east-1"
      stack: "prod"

The preceding example adds region and stack tags to all observations with a value of us-east-1 and prod, respectively.

Preventing Observations

If you’d like to prevent some observations from being reported, you can use the management.observations.enable properties:

  • Properties

  • YAML

management.observations.enable.denied.prefix=false
management.observations.enable.another.denied.prefix=false
management:
  observations:
    enable:
      denied:
        prefix: false
      another:
        denied:
          prefix: false

The preceding example will prevent all observations with a name starting with denied.prefix or another.denied.prefix.

If you want to prevent Spring Security from reporting observations, set the property management.observations.enable.spring.security to false.

If you need greater control over the prevention of observations, you can register beans of type ObservationPredicate. Observations are only reported if all the ObservationPredicate beans return true for that observation.

import io.micrometer.observation.Observation.Context;
import io.micrometer.observation.ObservationPredicate;

import org.springframework.stereotype.Component;

@Component
class MyObservationPredicate implements ObservationPredicate {

	@Override
	public boolean test(String name, Context context) {
		return !name.contains("denied");
	}

}

The preceding example will prevent all observations whose name contains "denied".

OpenTelemetry Support

There are several ways to support OpenTelemetry in your application. You can use the OpenTelemetry Java Agent or the OpenTelemetry Spring Boot Starter, which are supported by the OTel community; the metrics and traces use the semantic conventions defined by OTel libraries. This documentation describes OpenTelemetry as officially supported by the Spring team, using Micrometer and the OTLP exporter; the metrics and traces use the semantic conventions described in the Spring projects documentation, such as Spring Framework.

Spring Boot’s actuator module includes basic support for OpenTelemetry.

It provides a bean of type OpenTelemetry, and if there are beans of type SdkTracerProvider, ContextPropagators, SdkLoggerProvider or SdkMeterProvider in the application context, they automatically get registered. Additionally, it provides a Resource bean. The attributes of the auto-configured Resource can be configured via the management.opentelemetry.resource-attributes configuration property. If you have defined your own Resource bean, this will no longer be the case.

Spring Boot does not provide auto-configuration for OpenTelemetry metrics or logging. OpenTelemetry tracing is only auto-configured when used together with Micrometer Tracing.

The next sections will provide more details about logging, metrics and traces.

Micrometer Observation Annotations support

To enable scanning of metrics and tracing annotations like @Timed, @Counted, @MeterTag and @NewSpan annotations, you will need to set the management.observations.annotations.enabled property to true. This feature is supported Micrometer directly. Please refer to the Micrometer and Micrometer Tracing reference docs.