Actuator-Note
reference
https://docs.spring.io/spring-boot/3.3/reference/actuator/enabling.html
To add the actuator to a Maven-based project, add the following starter dependency:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
[API documentation : https://docs.spring.io/spring-boot/3.3/api/rest/actuator/index.html
Endpoints
Actuator endpoints let you monitor and interact with your application. Spring Boot includes a number of built-in endpoints and lets you add your own. For example, the health
endpoint provides basic application health information.
You can enable or disable each individual endpoint and expose them (make them remotely accessible) over HTTP or JMX. An endpoint is considered to be available when it is both enabled and exposed. The built-in endpoints are auto-configured only when they are available. Most applications choose exposure over HTTP, where the ID of the endpoint and a prefix of /actuator
is mapped to a URL. For example, by default, the health
endpoint is mapped to /actuator/health
.
The following technology-agnostic endpoints are available:
ID | Description |
---|---|
auditevents |
Exposes audit events information for the current application. Requires anAuditEventRepository bean. |
beans |
Displays a complete list of all the Spring beans in your application. |
caches |
Exposes available caches. |
conditions |
Shows the conditions that were evaluated on configuration and auto-configuration classes and the reasons why they did or did not match. |
configprops |
Displays a collated list of all@ConfigurationProperties . Subject tosanitization. |
env |
Exposes properties from Spring’sConfigurableEnvironment . Subject tosanitization. |
flyway |
Shows any Flyway database migrations that have been applied. Requires one or moreFlyway beans. |
health |
Shows application health information. |
httpexchanges |
Displays HTTP exchange information (by default, the last 100 HTTP request-response exchanges). Requires anHttpExchangeRepository bean. |
info |
Displays arbitrary application info. |
integrationgraph |
Shows the Spring Integration graph. Requires a dependency on spring-integration-core . |
loggers |
Shows and modifies the configuration of loggers in the application. |
liquibase |
Shows any Liquibase database migrations that have been applied. Requires one or moreLiquibase beans. |
metrics |
Shows “metrics” information for the current application to diagnose the metrics the application has recorded. |
mappings |
Displays a collated list of all@RequestMapping paths. |
quartz |
Shows information about Quartz Scheduler jobs. Subject tosanitization. |
scheduledtasks |
Displays the scheduled tasks in your application. |
sessions |
Allows retrieval and deletion of user sessions from a Spring Session-backed session store. Requires a servlet-based web application that uses Spring Session. |
shutdown |
Lets the application be gracefully shutdown. Only works when using jar packaging. Disabled by default. |
startup |
Shows thestartup steps datacollected by theApplicationStartup . Requires theSpringApplication to be configured with aBufferingApplicationStartup . |
threaddump |
Performs a thread dump. |
If your application is a web application (Spring MVC, Spring WebFlux, or Jersey), you can use the following additional endpoints:
ID | Description |
---|---|
heapdump |
Returns a heap dump file. On a HotSpot JVM, an HPROF -format file is returned. On an OpenJ9 JVM, a PHD -format file is returned. |
logfile |
Returns the contents of the logfile (if the logging.file.name or the logging.file.path property has been set). Supports the use of the HTTP Range header to retrieve part of the log file’s content. |
prometheus |
Exposes metrics in a format that can be scraped by a Prometheus server. Requires a dependency on micrometer-registry-prometheus . |
Enabling Endpoints
By default, all endpoints except for shutdown
are enabled. To configure the enablement of an endpoint, use its management.endpoint.<id>.enabled
property. The following example enables the shutdown
endpoint:
management:
endpoint:
shutdown:
enabled: true
If you prefer endpoint enablement to be opt-in rather than opt-out, set the management.endpoints.enabled-by-default
property to false
and use individual endpoint enabled
properties to opt back in. The following example enables the info
endpoint and disables all other endpoints:
management:
endpoints:
enabled-by-default: false
endpoint:
info:
enabled: true
Exposing Endpoints
By default, only the health endpoint is exposed over HTTP and JMX. Since Endpoints may contain sensitive information, you should carefully consider when to expose them.
To change which endpoints are exposed, use the following technology-specific include
and exclude
properties:
Property | Default |
---|---|
management.endpoints.jmx.exposure.exclude |
|
management.endpoints.jmx.exposure.include |
health |
management.endpoints.web.exposure.exclude |
|
management.endpoints.web.exposure.include |
health |
The include
property lists the IDs of the endpoints that are exposed. The exclude
property lists the IDs of the endpoints that should not be exposed. The exclude
property takes precedence over the include
property. You can configure both the include
and the exclude
properties with a list of endpoint IDs.
For example, to only expose the health
and info
endpoints over JMX, use the following property:
management:
endpoints:
jmx:
exposure:
include: "health,info"
*
can be used to select all endpoints. For example, to expose everything over HTTP except the env
and beans
endpoints, use the following properties:
management:
endpoints:
web:
exposure:
include: "*"
exclude: "env,beans"
*
has a special meaning in YAML, so be sure to add quotation marks if you want to include (or exclude) all endpoints.
If your application is exposed publicly, we strongly recommend that you also secure your endpoints.
If you want to implement your own strategy for when endpoints are exposed, you can register an EndpointFilter bean.
Security
For security purposes, only the /health
endpoint is exposed over HTTP by default. You can use the management.endpoints.web.exposure.include
property to configure the endpoints that are exposed.
If Spring Security is on the classpath and no other SecurityFilterChain
bean is present, all actuators other than /health
are secured by Spring Boot auto-configuration. If you define a custom SecurityFilterChain
bean, Spring Boot auto-configuration backs off and lets you fully control the actuator access rules.
If you wish to configure custom security for HTTP endpoints (for example, to allow only users with a certain role to access them), Spring Boot provides some convenient RequestMatcher
objects that you can use in combination with Spring Security.
A typical Spring Security configuration might look something like the following example:
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import static org.springframework.security.config.Customizer.withDefaults;
@Configuration(proxyBeanMethods = false)
public class MySecurityConfiguration {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.securityMatcher(EndpointRequest.toAnyEndpoint());
http.authorizeHttpRequests((requests) -> requests.anyRequest().hasRole("ENDPOINT_ADMIN"));
http.httpBasic(withDefaults());
return http.build();
}
}
The preceding example uses EndpointRequest.toAnyEndpoint()
to match a request to any endpoint and then ensures that all have the ENDPOINT_ADMIN
role. Several other matcher methods are also available on EndpointRequest
. See the API documentation for details.
If you deploy applications behind a firewall, you may prefer that all your actuator endpoints can be accessed without requiring authentication. You can do so by changing the management.endpoints.web.exposure.include
property, as follows:
management:
endpoints:
web:
exposure:
include: "*"
Additionally, if Spring Security is present, you would need to add custom security configuration that allows unauthenticated access to the endpoints, as the following example shows:
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration(proxyBeanMethods = false)
public class MySecurityConfiguration {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.securityMatcher(EndpointRequest.toAnyEndpoint());
http.authorizeHttpRequests((requests) -> requests.anyRequest().permitAll());
return http.build();
}
}
In both of the preceding examples, the configuration applies only to the actuator endpoints. Since Spring Boot’s security configuration backs off completely in the presence of any SecurityFilterChain
bean, you need to configure an additional SecurityFilterChain
bean with rules that apply to the rest of the application.
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
.
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:
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:
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
.
Tip: 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
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.
Micrometer Observation Annotations support
To enable scanning of observability annotations like @Observed
, @Timed
, @Counted
, @MeterTag
and @NewSpan
, you need to set the management.observations.annotations.enabled
property to true
. This feature is supported by Micrometer directly. Please refer to the Micrometer, Micrometer Observation and Micrometer Tracing reference docs.
Loggers
Spring Boot Actuator includes the ability to view and configure the log levels of your application at runtime. You can view either the entire list or an individual logger’s configuration, which is made up of both the explicitly configured logging level as well as the effective logging level given to it by the logging framework. These levels can be one of:
TRACE
DEBUG
INFO
WARN
ERROR
FATAL
OFF
null
null
indicates that there is no explicit configuration.
Metrics
Spring Boot Actuator provides dependency management and auto-configuration for Micrometer, an application metrics facade that supports numerous monitoring systems, including:
- AppOptics
- Atlas
- Datadog
- Dynatrace
- Elastic
- Ganglia
- Graphite
- Humio
- Influx
- JMX
- KairosDB
- New Relic
- OTLP
- Prometheus
- SignalFx
- Simple (in-memory)
- Stackdriver
- StatsD
- Wavefront
Getting Started
Spring Boot auto-configures a composite MeterRegistry
and adds a registry to the composite for each of the supported implementations that it finds on the classpath. Having a dependency on micrometer-registry-{system}
in your runtime classpath is enough for Spring Boot to configure the registry.
Most registries share common features. For instance, you can disable a particular registry even if the Micrometer registry implementation is on the classpath. The following example disables Datadog:
management:
datadog:
metrics:
export:
enabled: false
You can also disable all registries unless stated otherwise by the registry-specific property, as the following example shows:
management:
defaults:
metrics:
export:
enabled: false
Spring Boot also adds any auto-configured registries to the global static composite registry on the Metrics
class, unless you explicitly tell it not to:
management:
metrics:
use-global-registry: false
You can register any number of MeterRegistryCustomizer
beans to further configure the registry, such as applying common tags, before any meters are registered with the registry:
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyMeterRegistryConfiguration {
@Bean
public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
return (registry) -> registry.config().commonTags("region", "us-east-1");
}
}
You can apply customizations to particular registry implementations by being more specific about the generic type:
import io.micrometer.core.instrument.Meter;
import io.micrometer.core.instrument.config.NamingConvention;
import io.micrometer.graphite.GraphiteMeterRegistry;
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyMeterRegistryConfiguration {
@Bean
public MeterRegistryCustomizer<GraphiteMeterRegistry> graphiteMetricsNamingConvention() {
return (registry) -> registry.config().namingConvention(this::name);
}
private String name(String name, Meter.Type type, String baseUnit) {
return ...
}
}
Supported Monitoring Systems
This section briefly describes each of the supported monitoring systems.
OTLP
By default, metrics are exported over the OpenTelemetry protocol (OTLP) to a consumer running on your local machine. To export to another location, provide the location of the OTLP metrics endpoint using management.otlp.metrics.export.url
:
management:
otlp:
metrics:
export:
url: "https://otlp.example.com:4318/v1/metrics"
Custom headers, for example for authentication, can also be provided using management.otlp.metrics.export.headers.*
properties.
Supported Metrics and Meters
Spring Boot provides automatic meter registration for a wide variety of technologies. In most situations, the defaults provide sensible metrics that can be published to any of the supported monitoring systems.
JVM Metrics
Auto-configuration enables JVM Metrics by using core Micrometer classes. JVM metrics are published under the jvm.
meter name.
The following JVM metrics are provided:
- Various memory and buffer pool details
- Statistics related to garbage collection
- Thread utilization
- The number of classes loaded and unloaded
- JVM version information
- JIT compilation time
System Metrics
Auto-configuration enables system metrics by using core Micrometer classes. System metrics are published under the system.
, process.
, and disk.
meter names.
The following system metrics are provided:
- CPU metrics
- File descriptor metrics
- Uptime metrics (both the amount of time the application has been running and a fixed gauge of the absolute start time)
- Disk space available
Application Startup Metrics
Auto-configuration exposes application startup time metrics:
application.started.time
: time taken to start the application.application.ready.time
: time taken for the application to be ready to service requests.
Metrics are tagged by the fully qualified name of the application class.
Tomcat Metrics
Auto-configuration enables the instrumentation of Tomcat only when an MBean Registry
is enabled. By default, the MBean registry is disabled, but you can enable it by setting server.tomcat.mbeanregistry.enabled
to true
.
Tomcat metrics are published under the tomcat.
meter name.
Registering Custom Metrics
To register custom metrics, inject MeterRegistry
into your component:
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tags;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
private final Dictionary dictionary;
public MyBean(MeterRegistry registry) {
this.dictionary = Dictionary.load();
registry.gauge("dictionary.size", Tags.empty(), this.dictionary.getWords().size());
}
}
If your metrics depend on other beans, we recommend that you use a MeterBinder
to register them:
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.binder.MeterBinder;
import org.springframework.context.annotation.Bean;
public class MyMeterBinderConfiguration {
@Bean
public MeterBinder queueSize(Queue queue) {
return (registry) -> Gauge.builder("queueSize", queue::size).register(registry);
}
}
Using a MeterBinder
ensures that the correct dependency relationships are set up and that the bean is available when the metric’s value is retrieved. A MeterBinder
implementation can also be useful if you find that you repeatedly instrument a suite of metrics across components or applications.
By default, metrics from all MeterBinder
beans are automatically bound to the Spring-managed MeterRegistry
.
Metrics Endpoint
Spring Boot provides a metrics
endpoint that you can use diagnostically to examine the metrics collected by an application. The endpoint is not available by default and must be exposed. See exposing endpoints for more details.
Navigating to /actuator/metrics
displays a list of available meter names. You can drill down to view information about a particular meter by providing its name as a selector — for example, /actuator/metrics/jvm.memory.max
.
tip: The name you use here should match the name used in the code, not the name after it has been naming-convention normalized for a monitoring system to which it is shipped. In other words, if jvm.memory.max appears as jvm_memory_max in Prometheus because of its snake case naming convention, you should still use jvm.memory.max as the selector when inspecting the meter in the metrics endpoint.
You can also add any number of tag=KEY:VALUE
query parameters to the end of the URL to dimensionally drill down on a meter — for example, /actuator/metrics/jvm.memory.max?tag=area:nonheap
.
The reported measurements are the sum of the statistics of all meters that match the meter name and any tags that have been applied. In the preceding example, the returned Value statistic is the sum of the maximum memory footprints of the “Code Cache”, “Compressed Class Space”, and “Metaspace” areas of the heap. If you wanted to see only the maximum size for the “Metaspace”, you could add an additional tag=id:Metaspace — that is, /actuator/metrics/jvm.memory.max?tag=area:nonheap&tag=id:Metaspace.
Tracing
Spring Boot Actuator provides dependency management and auto-configuration for Micrometer Tracing, a facade for popular tracer libraries.
Supported Tracers
Spring Boot ships auto-configuration for the following tracers:
- OpenTelemetry with Zipkin, Wavefront, or OTLP
- OpenZipkin Brave with Zipkin or Wavefront
Getting Started
We need an example application that we can use to get started with tracing. For our purposes, the simple “Hello World!” web application that’s covered in the Developing Your First Spring Boot Application section will suffice. We’re going to use the OpenTelemetry tracer with Zipkin as trace backend.
To recap, our main application code looks like this:
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication
public class MyApplication {
private static final Log logger = LogFactory.getLog(MyApplication.class);
@RequestMapping("/")
String home() {
logger.info("home() has been called");
return "Hello World!";
}
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Now we have to add the following dependencies:
org.springframework.boot:spring-boot-starter-actuator
io.micrometer:micrometer-tracing-bridge-otel
- bridges the Micrometer Observation API to OpenTelemetry.io.opentelemetry:opentelemetry-exporter-zipkin
- reports traces to Zipkin.
Add the following application properties:
management:
tracing:
sampling:
probability: 1.0
By default, Spring Boot samples only 10% of requests to prevent overwhelming the trace backend. This property switches it to 100% so that every request is sent to the trace backend.
To collect and visualize the traces, we need a running trace backend. We use Zipkin as our trace backend here. The Zipkin Quickstart guide provides instructions how to start Zipkin locally.
After Zipkin is running, you can start your application.
If you open a web browser to [localhost:8080](http://localhost:8080/)
, you should see the following output:
Hello World!
Behind the scenes, an observation has been created for the HTTP request, which in turn gets bridged to OpenTelemetry, which reports a new trace to Zipkin.
Now open the Zipkin UI at [localhost:9411](http://localhost:9411/)
and press the "Run Query" button to list all collected traces. You should see one trace. Press the "Show" button to see the details of that trace.
Logging Correlation IDs
Correlation IDs provide a helpful way to link lines in your log files to spans/traces. If you are using Micrometer Tracing, Spring Boot will include correlation IDs in your logs by default.
The default correlation ID is built from traceId
and spanId
MDC values. For example, if Micrometer Tracing has added an MDC traceId
of 803B448A0489F84084905D3093480352
and an MDC spanId
of 3425F23BB2432450
the log output will include the correlation ID [803B448A0489F84084905D3093480352-3425F23BB2432450]
.
If you prefer to use a different format for your correlation ID, you can use the logging.pattern.correlation
property to define one. For example, the following will provide a correlation ID for Logback in format previously used by Spring Cloud Sleuth:
logging:
pattern:
correlation: "[${spring.application.name:},%X{traceId:-},%X{spanId:-}] "
include-application-name: false
Note: In the example above, logging.include-application-name
is set to false
to avoid the application name being duplicated in the log messages (logging.pattern.correlation
already contains it). It’s also worth mentioning that logging.pattern.correlation
contains a trailing space so that it is separated from the logger name that comes right after it by default.
Propagating Traces
To automatically propagate traces over the network, use the auto-configured RestTemplateBuilder
, RestClient.Builder
or WebClient.Builder
to construct the client.
Warning: If you create the RestTemplate
, the RestClient
or the WebClient
without using the auto-configured builders, automatic trace propagation won’t work!
Tracer Implementations
As Micrometer Tracer supports multiple tracer implementations, there are multiple dependency combinations possible with Spring Boot.
All tracer implementations need the org.springframework.boot:spring-boot-starter-actuator
dependency.
OpenTelemetry With Zipkin
Tracing with OpenTelemetry and reporting to Zipkin requires the following dependencies:
io.micrometer:micrometer-tracing-bridge-otel
- bridges the Micrometer Observation API to OpenTelemetry.io.opentelemetry:opentelemetry-exporter-zipkin
- reports traces to Zipkin.
Use the management.zipkin.tracing.*
configuration properties to configure reporting to Zipkin.
OpenTelemetry With OTLP
Tracing with OpenTelemetry and reporting using OTLP requires the following dependencies:
io.micrometer:micrometer-tracing-bridge-otel
- bridges the Micrometer Observation API to OpenTelemetry.io.opentelemetry:opentelemetry-exporter-otlp
- reports traces to a collector that can accept OTLP.
Use the management.otlp.tracing.*
configuration properties to configure reporting using OTLP.
梳理思路
当需要使用到metrics功能的时候,就会涉及到将采集到的各个metrics值,转成各种监控系统的格式,然后发送到各监控系统中,所以需要引入各种监控系统的依赖包,格式是micrometer-registry-{system}
一般来说,只要引入了该监控系统的依赖包,那么将此监控系统,自动配置到CompositeMeterRegistry中,那么,我们在创建自定义的metrics时,只需要注册到CompositeMeterRegistry后,自定义的metrics就会发送到此监控系统中了。
- OpenTelemetry Protocol (OTLP). OpenTelemetry is a CNCF incubating project for providing standards for telemetry data. Micrometer can publish metrics using the OpenTelemetry protocol (OTLP) to the backends that support it.
当需要使用到tracing功能时,我们需要考虑2个概念:bridge 和 exporter。所以,要引入相关的依赖包。
Tracing with OpenTelemetry and reporting using OTLP requires the following dependencies:
io.micrometer:micrometer-tracing-bridge-otel
- bridges the Micrometer Observation API to OpenTelemetry.io.opentelemetry:opentelemetry-exporter-otlp
- reports traces to a collector that can accept OTLP.
Metrics 示例
Creating and Using Metrics
Micrometer provides several types of meters you can use to measure different aspects of your application. Here are some common ones:
Counters
A counter is a simple incrementing and decrementing metric that represents a count.
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
@RestController
public class MyController {
private final Counter myCounter;
public MyController(MeterRegistry registry) {
myCounter = Counter.builder("my.counter")
.description("Counts something")
.tags("region", "us-east")
.register(registry);
}
@GetMapping("/increment")
public void incrementCounter() {
myCounter.increment();
}
}
Timers
Timers are used to measure the duration of events and the rate at which they occur.
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.MeterRegistry;
@RestController
public class MyController {
private final Timer myTimer;
public MyController(MeterRegistry registry) {
myTimer = Timer.builder("my.timer")
.description("Times something")
.tags("region", "us-east")
.register(registry);
}
@GetMapping("/time")
public void timeSomething() {
myTimer.record(() -> {
// perform task to be timed
});
}
}
Gauges
Gauges are used to measure a value at a specific point in time, such as the size of a collection or the amount of free memory.
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import java.util.concurrent.atomic.AtomicInteger;
@RestController
public class MyController {
private final AtomicInteger myGauge = new AtomicInteger();
public MyController(MeterRegistry registry) {
Gauge.builder("my.gauge", myGauge, AtomicInteger::get)
.description("Gauges something")
.tags("region", "us-east")
.register(registry);
}
@GetMapping("/setGauge")
public void setGauge(@RequestParam int value) {
myGauge.set(value);
}
}
Customizing Metrics
You can customize metrics by adding tags, descriptions, and more. This provides more context and makes them more meaningful when analyzing the data.
Counter.builder("custom.counter")
.description("A custom counter")
.tags("env", "production")
.register(meterRegistry);
Viewing and Analyzing Metrics
Once you have your metrics in place and your application is running, you can view and analyze them using the backend you’ve configured. For example, if you’re using Prometheus, you can visit the /actuator/prometheus
endpoint to see your metrics in a format that Prometheus can scrape.
在 Spring Boot 3.3 中,MeterBinder 是 Micrometer 框架中用于将自定义监控指标与 MeterRegistry
绑定的核心接口。它通过标准化方式将业务逻辑中的度量数据集成到 Spring Boot Actuator 的监控体系中,是自定义指标的核心实现机制。
MeterBinder
MeterBinder 的核心作用
- 统一指标注册入口
通过实现MeterBinder
接口,开发者可以将自定义的指标(如数据库连接池状态、业务订单量等)统一注册到MeterRegistry
,并由 Spring Boot Actuator 的/metrics
端点自动暴露。 - 解耦业务与监控代码
将指标绑定逻辑封装在MeterBinder
实现类中,避免在业务代码中直接操作MeterRegistry
,提升代码可维护性。 - 支持动态指标管理
结合 Spring 的依赖注入机制,可实现动态绑定/解绑指标(例如根据运行时条件注册不同的指标)。
MeterBinder 的工作机制
-
接口定义
MeterBinder
接口仅包含一个方法:
java
复制void bindTo(MeterRegistry registry);
开发者需实现此方法,并在其中定义指标注册逻辑。
-
Spring Boot 集成
- Spring Boot 会自动扫描所有实现
MeterBinder
的 Bean,并在应用启动时调用bindTo
方法。 - 指标数据会通过 Actuator 的
/actuator/metrics
或/actuator/prometheus
端点暴露。
- Spring Boot 会自动扫描所有实现
具体示例:监控数据库连接池
步骤 1:实现 MeterBinder 类
java
复制
@Component
public class DataSourceMetricsBinder implements MeterBinder {
private final DataSource dataSource;
@Autowired
public DataSourceMetricsBinder(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public void bindTo(MeterRegistry registry) {
// 监控活跃连接数
Gauge.builder("db.pool.active.connections", dataSource, ds -> {
try (Connection conn = ds.getConnection()) {
return conn.unwrap(PoolDataSource.class).getActiveConnections();
} catch (SQLException e) {
return 0;
}
}).register(registry);
// 监控连接池总大小
Gauge.builder("db.pool.total.size", dataSource, ds -> {
try (Connection conn = ds.getConnection()) {
return conn.unwrap(PoolDataSource.class).getPoolSize();
} catch (SQLException e) {
return 0;
}
}).register(registry);
}
}
步骤 2:通过 Actuator 查看指标
启动应用后,访问 /actuator/metrics/db.pool.active.connections
,可获取如下 Prometheus 格式数据:
markdown
复制
db_pool_active_connections{application="order-service", env="prod"} 15
应用场景与最佳实践
1. 业务指标监控(如订单处理)
java
复制
public class OrderMetricsBinder implements MeterBinder {
private final OrderService orderService;
public OrderMetricsBinder(OrderService orderService) {
this.orderService = orderService;
}
@Override
public void bindTo(MeterRegistry registry) {
// 统计每分钟订单创建量
Meter.builder("orders.created", orderService, os -> os.getCreatedOrdersCount())
.tag("type", "realtime")
.register(registry);
}
}
此指标可通过 Grafana 仪表盘实时展示订单趋势。
2. 系统资源监控(如线程池)
java
复制
public class ThreadPoolBinder implements MeterBinder {
private final ThreadPoolExecutor executor;
public ThreadPoolBinder(ThreadPoolExecutor executor) {
this.executor = executor;
}
@Override
public void bindTo(MeterRegistry registry) {
Gauge.builder("thread.pool.active", executor, ThreadPoolExecutor::getActiveCount)
.description("当前活跃线程数")
.register(registry);
}
}
3. 最佳实践
- 标签规范化:使用一致的标签命名(如
service="payment"
),避免因标签维度爆炸导致监控系统压力。 - 指标生命周期管理:通过
MeterRegistry.remove()
动态清理无用指标,防止内存泄漏。 - 全局配置:在
MeterBinder
中调用registry.config().commonTags("region", "us-east")
添加统一标签。
与 Spring Boot 3.3 的深度集成
- 自动绑定优化
Spring Boot 3.3 增强了对MeterBinder
实现类的自动发现机制,即使指标类未标注@Component
,也能通过META-INF/spring.factories
配置加载。 - 性能提升
新版本中MeterBinder
的指标注册过程采用异步化处理,减少对应用启动速度的影响。
总结
MeterBinder 是 Spring Boot 监控体系中的核心扩展点,通过标准化接口将业务指标无缝集成到 Micrometer 生态中。结合 Spring Boot 3.3 的自动化能力(如依赖注入、端点暴露),开发者可以高效构建多维度的可观测性系统。
实际演练
基础配置
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
application.yaml
spring:
application:
name: trace-metric-demo
management:
endpoints:
enabled-by-default: false
web:
exposure:
include:
- info
- health
- metrics
endpoint:
info:
enabled: true
health:
enabled: true
metrics:
enabled: true
上面的例子中,启用并暴露了3个endpoint,访问地址分别如下:
http://localhost:8080/actuator/health
http://localhost:8080/actuator/info
http://localhost:8080/actuator/metrics
其中,在访问health的endpoint时,响应如下:
{"status":"UP"}
在访问metrics的endpoint时,响应如下:
{
"names": [
"application.ready.time",
"application.started.time",
"disk.free",
"disk.total",
"executor.active",
"executor.completed",
"executor.pool.core",
"executor.pool.max",
"executor.pool.size",
"executor.queue.remaining",
"executor.queued",
"http.server.requests.active",
"jvm.buffer.count",
"jvm.buffer.memory.used",
"jvm.buffer.total.capacity",
"jvm.classes.loaded",
"jvm.classes.unloaded",
"jvm.compilation.time",
"jvm.gc.live.data.size",
"jvm.gc.max.data.size",
"jvm.gc.memory.allocated",
"jvm.gc.memory.promoted",
"jvm.gc.overhead",
"jvm.info",
"jvm.memory.committed",
"jvm.memory.max",
"jvm.memory.usage.after.gc",
"jvm.memory.used",
"jvm.threads.daemon",
"jvm.threads.live",
"jvm.threads.peak",
"jvm.threads.started",
"jvm.threads.states",
"logback.events",
"process.cpu.time",
"process.cpu.usage",
"process.start.time",
"process.uptime",
"system.cpu.count",
"system.cpu.usage",
"tomcat.sessions.active.current",
"tomcat.sessions.active.max",
"tomcat.sessions.alive.max",
"tomcat.sessions.created",
"tomcat.sessions.expired",
"tomcat.sessions.rejected"
]
}
接下来,获取某个具体指标值时,访问路径如下:
http://localhost:8080/actuator/metrics/jvm.memory.max
响应如下:
{
"name": "jvm.memory.max",
"description": "The maximum amount of memory in bytes that can be used for memory management",
"baseUnit": "bytes",
"measurements": [
{
"statistic": "VALUE",
"value": 5337251837.0
}
],
"availableTags": [
{
"tag": "area",
"values": [
"heap",
"nonheap"
]
},
{
"tag": "id",
"values": [
"G1 Survivor Space",
"Compressed Class Space",
"CodeCache",
"G1 Old Gen",
"Metaspace",
"G1 Eden Space"
]
}
]
}
支持prometheus
增加以下依赖:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
在yaml中,增加对prometheus endpoint的enabled & exported,配置如下:
management:
endpoints:
enabled-by-default: false
web:
exposure:
include:
- info
- health
- metrics
- prometheus
endpoint:
info:
enabled: true
health:
enabled: true
metrics:
enabled: true
prometheus:
enabled: true
支持otel
pom.xml中,增加以下依赖:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-otlp</artifactId>
</dependency>
yaml中增加以下配置:
management:
otlp:
metrics:
export:
url: http://localhost:4318/v1/metrics # URI of the OLTP server.
因为,otel不像prometheus一样,有默认的endpoint可以直接访问,所以需要先在本地安装open telemetry collector。
从gitHub上下载otelcol-contrib_0.124.1_windows_amd64,新建一个config.yaml,内容如下:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
exporters:
debug:
verbosity: detailed
file:
path: ./metrics-otlp.json # 为了方便查看,这里我将指标信息直接 export 到文件中
service:
pipelines:
metrics:
receivers: [otlp] # 使用 otlp
exporters: [file] # 使用 file
接下来,启动open telemetry collector,命令如下:
.\otelcol-contrib.exe --config=config.yaml
接下来,我们再启动我们的springboot项目,就能发现,metrics信息,被发送到了open telemetry collector中,我们可以在上面配置的path: ./metric文件中,看到metrics信息。
支持Tracing
pom.xml,增加以下依赖:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-otel</artifactId>
</dependency>
配置文件,增加以下配置项:
management:
tracing:
sampling:
probability: 1.0
上面的配置完成后,那么就可以在日志中,打印出traceid 和 spanid了
logback的配置如下:
<variable name="log.pattern" value="%d{HH:mm:ss.SSS} [%X{traceId:-},%X{spanId:-}] [%thread] %-5level %logger{40} - [%method,%line] - %msg%n" />
打印的日志如下:
14:00:49.084 [4b8e75a49841815b82f432325bdb5294,ef1784736da5501b] [http-nio-8080-exec-1] INFO c.w.t.controller.HahaController - [hello,16] -
inputed name is lisi
如果说,想要将trace的相关信息,发送到otlp中,那么还需要增加以下依赖:
io.opentelemetry:opentelemetry-exporter-otlp
- reports traces to a collector that can accept OTLP.
文章作者:Administrator
文章链接:http://localhost:8090//archives/actuator-note
版权声明:本博客所有文章除特别声明外,均采用CC BY-NC-SA 4.0 许可协议,转载请注明出处!
评论