57、指标
Spring Boot Actuator 为 Micrometer 提供了依赖管理和自动配置,Micrometer 是一个支持众多监控系统的应用程序指标门面,包括:
- AppOptics
- Atlas
- Datadog
- Dynatrace
- Elastic
- Ganglia
- Graphite
- Humio
- Influx
- JMX
- KairosDB
- New Relic
- Prometheus
- SignalFx
- Simple (in-memory)
- StatsD
- Wavefront
提示
要了解有关 Micrometer 功能的更多信息,请参阅其参考文档,特别是概念部分。
57.1、入门
Spring Boot 自动配置了一个组合的 MeterRegistry
,并为 classpath 中每个受支持的实现向该组合注册一个注册表。在运行时,只需要 classpath 中有 micrometer-registry-{system}
依赖即可让 Spring Boot 配置该注册表。
大部分注册表都有共同点 例如,即使 Micrometer 注册实现位于 classpath 上,你也可以禁用特定的注册表。例如,要禁用 Datadog:
management.metrics.export.datadog.enabled=false
Spring Boot 还会将所有自动配置的注册表添加到 Metrics
类的全局静态复合注册表中,除非你明确禁止:
management.metrics.use-global-registry=false
在注册表中注册任何指标之前,你可以注册任意数量的 MeterRegistryCustomizer
bean 以进一步配置注册表,例如通用标签:
@Bean
MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
return registry -> registry.config().commonTags("region", "us-east-1");
}
你可以通过指定泛型类型,自定义注册表实现:
@Bean
MeterRegistryCustomizer<GraphiteMeterRegistry> graphiteMetricsNamingConvention() {
return registry -> registry.config().namingConvention(MY_CUSTOM_CONVENTION);
}
使用该设置,你可以在组件中注入 MeterRegistry
并注册指标:
@Component
public class SampleBean {
private final Counter counter;
public SampleBean(MeterRegistry registry) {
this.counter = registry.counter("received.messages");
}
public void handleMessage(String message) {
this.counter.increment();
// 处理消息实现
}
}
Spring Boot 还配置内置的测量工具(即 MeterBinder
实现),你可以通过配置或专用注解标记来控制。
57.2、支持的监控系统
57.2.1、AppOptics
默认情况下,AppOptics 注册表会定期将指标推送到 api.appoptics.com/v1/measurements。要将指标导出到 SaaS AppOptics,你必须提供 API 令牌:
management.metrics.export.appoptics.api-token=YOUR_TOKEN
57.2.2、Atlas
默认情况下,度量标准将导出到本地的 Atlas。可以使用以下方式指定 Atlas 服务器的位置:
management.metrics.export.atlas.uri=https://atlas.example.com:7101/api/v1/publish
57.2.3、Datadog
Datadog 注册表会定期将指标推送到 datadoghq。要将指标导出到 Datadog,你必须提供 API 密钥:
management.metrics.export.datadog.api-key=YOUR_KEY
你还可以更改度量标准发送到 Datadog 的间隔时间:
management.metrics.export.datadog.step=30s
57.2.4、Dynatrace
Dynatrace 注册表定期将指标推送到配置的 URI。要将指标导出到 Dynatrace,必须提供 API 令牌、设备 ID 和 URI:
management.metrics.export.dynatrace.api-token=YOUR_TOKEN
management.metrics.export.dynatrace.device-id=YOUR_DEVICE_ID
management.metrics.export.dynatrace.uri=YOUR_URI
你还可以更改度量标准发送到 Dynatrace 的间隔时间:
management.metrics.export.dynatrace.step=30s
57.2.5、Elastic
默认情况下,度量将导出到本地的 Elastic。可以使用以下属性提供 Elastic 服务器的位置:
management.metrics.export.elastic.host=https://elastic.example.com:8086
57.2.6、Ganglia
默认情况下,度量将导出到本地的 Ganglia。可以使用以下方式提供 Ganglia 服务器主机和端口:
management.metrics.export.ganglia.host=ganglia.example.com
management.metrics.export.ganglia.port=9649
57.2.7、Graphite
默认情况下,度量将导出到本地的 Graphite。可以使用以下方式提供 Graphite 服务器主机和端口:
management.metrics.export.graphite.host=graphite.example.com
management.metrics.export.graphite.port=9004
Micrometer 提供了一个默认的 HierarchicalNameMapper
,它管理维度计数器 id 如何映射到平面分层名称。
提示
要控制此行为,请定义
GraphiteMeterRegistry
并提供自己的HierarchicalNameMapper
。除非你自己定义,否则使用自动配置的GraphiteConfig
和Clock
bean:
@Bean
public GraphiteMeterRegistry graphiteMeterRegistry(GraphiteConfig config, Clock clock) {
return new GraphiteMeterRegistry(config, clock, MY_HIERARCHICAL_MAPPER);
}
57.2.8、Humio
默认情况下,Humio 注册表会定期将指标推送到 cloud.humio.com。要将指标导出到 SaaS Humio,你必须提供 API 令牌:
management.metrics.export.humio.api-token=YOUR_TOKEN
你还应配置一个或多个标记,以标识要推送指标的数据源:
management.metrics.export.humio.tags.alpha=a
management.metrics.export.humio.tags.bravo=b
57.2.9、Influx
默认情况下,度量将导出到本地的 Influx。要指定 Influx 服务器的位置,可以使用:
management.metrics.export.influx.uri=https://influx.example.com:8086
57.2.10、JMX
Micrometer 提供了与 JMX 的分层映射,主要为了方便在本地查看指标且可移植。默认情况下,度量将导出到 metrics
JMX 域。可以使用以下方式提供要使用的域:
management.metrics.export.jmx.domain=com.example.app.metrics
Micrometer 提供了一个默认的 HierarchicalNameMapper
,它管理维度计数器 id 如何映射到平面分层名称。
提示
要控制此行为,请定义
JmxMeterRegistry
并提供自己的HierarchicalNameMapper
。除非你自己定义,否则使用自动配置的JmxConfig
和Clock
bean:
@Bean
public JmxMeterRegistry jmxMeterRegistry(JmxConfig config, Clock clock) {
return new JmxMeterRegistry(config, clock, MY_HIERARCHICAL_MAPPER);
}
57.2.11、KairosDB
默认情况下,度量将导出到本地的 KairosDB。可以使用以下方式提供 KairosDB 服务器的位置:
management.metrics.export.kairos.uri=https://kairosdb.example.com:8080/api/v1/datapoints
57.2.12、New Relic
New Relic 注册表定期将指标推送到 New Relic。要将指标导出到 New Relic,你必须提供 API 密钥和帐户 ID:
management.metrics.export.newrelic.api-key=YOUR_KEY
management.metrics.export.newrelic.account-id=YOUR_ACCOUNT_ID
你还可以更改将度量发送到 New Relic 的间隔时间:
management.metrics.export.newrelic.step=30s
57.2.13、Prometheus
Prometheus 希望抓取或轮询各个应用实例以获取指标数据。Spring Boot 在 /actuator/prometheus
上提供 actuator 端点,以适当的格式呈现 Prometheus scrape 。
提示
默认情况下端点不可用,必须暴露,请参阅暴露端点以获取更多详细信息。
以下是要添加到 prometheus.yml
的示例 scrape_config
:
scrape_configs:
- job_name: 'spring'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['HOST:PORT']
57.2.14、SignalFx
SignalFx 注册表定期将指标推送到 SignalFx。要将指标导出到 SignalFx,你必须提供访问令牌:
management.metrics.export.signalfx.access-token=YOUR_ACCESS_TOKEN
你还可以更改将指标发送到 SignalFx 的间隔时间:
management.metrics.export.signalfx.step=30s
57.2.15、Simple
Micrometer 附带一个简单的内存后端,如果没有配置其他注册表,它将自动用作后备。这使你可以查看指标端点中收集的指标信息。
只要你使用了任何其他可用的后端,内存后端就会自动禁用。你也可以显式禁用它:
management.metrics.export.simple.enabled=false
57.2.16、StatsD
StatsD 注册表将 UDP 上的指标推送到 StatsD 代理。 默认情况下,度量将导出到本地的 StatsD 代理,可以使用以下方式提供 StatsD 代理主机和端口:
management.metrics.export.statsd.host=statsd.example.com
management.metrics.export.statsd.port=9125
你还可以更改要使用的 StatsD 线路协议(默认为 Datadog):
management.metrics.export.statsd.flavor=etsy
57.2.17、Wavefront
Wavefront 注册表定期将指标推送到 Wavefront。如果要将指标直接导出到 Wavefront,则你必须提供 API 令牌:
management.metrics.export.wavefront.api-token=YOUR_API_TOKEN
或者,你可以在环境中使用 Wavefront sidecar 或内部代理设置,将指标数据转发到 Wavefront API 主机:
management.metrics.export.wavefront.uri=proxy://localhost:2878
提示
如果将度量发布到 Wavefront 代理(如文档中所述),则主机必须采用
proxy://HOST:PORT
格式。
你还可以更改将指标发送到 Wavefront 的间隔时间:
management.metrics.export.wavefront.step=30s
57.3、支持的指标
Spring Boot 在适当的环境注册以下核心指标:
- JVM 指标,报告利用率:
- 各种内存和缓冲池
- 与垃圾回收有关的统计
- 线程利用率
- 加载/卸载 class 的数量
- CPU 指标
- 文件描述符指标
- Kafka 消费者指标
- Log4j2 指标:记录每个级别记录到 Log4j2 的事件数
- Logback 指标:记录每个级别记录到 Logback 的事件数
- 正常运行时间指标:报告正常运行时间和表示应用程序绝对启动时间的固定计量值
- Tomcat 指标
- Spring Integration 指标
57.3.1、Spring MVC 指标
自动配置启用 Spring MVC 处理的请求的指标记录。当 management.metrics.web.server.auto-time-requests
为 true
时,将对所有请求进行此检测。或者,当设置为 false
时,你可以通过将 @Timed
添加到请求处理方法来启用检测:
@RestController
@Timed // <1>
public class MyController {
@GetMapping("/api/people")
@Timed(extraTags = { "region", "us-east-1" }) // <2>
@Timed(value = "all.people", longTask = true) // <3>
public List<Person> listPeople() { ... }
}
- 一个控制器类,为控制器中的每个请求处理程序启用计时。
- 启用单个端点。如果你在类上使用了它,就不需要在方法上再次声明,但可以用它来进一步自定义该特定端点的计时器。
- 使用
longTask = true
的方法为该方法启用长任务计时器。长任务计时器需要单独的指标名称,并且可以使用短任务计时器进行堆叠。
默认情况下,使用名称为 http.server.requests
生成度量指标。可以通过设置 management.metrics.web.server.requests-metric-name
属性来自定义名称。
默认情况下,Spring MVC 相关指标使用了以下标签标记:
标签 | 描述 |
---|---|
exception |
处理请求时抛出的异常的简单类名。 |
method |
请求的方法(例如,GET 或 POST ) |
outcome |
根据响应状态码生成结果。1xx 是 INFORMATIONAL ,2xx 是 SUCCESS ,3xx 是 REDIRECTION ,4xx 是 CLIENT_ERROR ,5xx 是 SERVER_ERROR |
status |
响应的 HTTP 状态码(例如,200 或 500 ) |
uri |
如果可能,在变量替换之前请求 URI 模板(例如,/api/person/{id} ) |
要自定义标签,请提供一个实现了 WebMvcTagsProvider
的 @Bean
。
57.3.2、Spring WebFlux 指标
自动配置启用了 WebFlux 控制器和函数式处理程序处理的所有请求的指标记录功能。
默认情况下,使用名为 http.server.requests
生成度量指标。你可以通过设置 management.metrics.web.server.requests-metric-name
属性来自定义名称。
默认情况下,与 WebFlux 相关的指标使用以下标签标记:
标签 | 描述 |
---|---|
exception |
处理请求时抛出的异常的简单类名。 |
method |
请求方法(例如,GET 或 POST ) |
outcome |
根据响应状态码生成请求结果。1xx 是 INFORMATIONAL ,2xx 是 SUCCESS ,3xx 是 REDIRECTION ,4xx 是 CLIENT_ERROR ,5xx 是 SERVER_ERROR |
status |
响应的 HTTP 状态码(例如,200 或 500 ) |
uri |
如果可能,在变量替换之前请求 URI 模板(例如,/api/person/{id} ) |
要自定义标签,请提供一个实现了 WebFluxTagsProvider
的 @Bean
。
57.3.3、Jersey Server 指标
自动配置启用了由 Jersey JAX-RS 实现处理的请求的指标记录功能。当 management.metrics.web.server.auto-time-requests
为 true
时,将对所有请求进行该项检测。当设置为 false
时,你可以通过将 @Timed
添加到请求处理方法上来启用检测:
@Component
@Path("/api/people")
@Timed // <1>
public class Endpoint {
@GET
@Timed(extraTags = { "region", "us-east-1" }) // <2>
@Timed(value = "all.people", longTask = true) // <3>
public List<Person> listPeople() { ... }
}
- 在资源类上,为资源中的每个请求处理程序启用计时。
- 在方法上则启用单个端点。如果你在类上使用了它,则不需在方法上再次声明,但可以用它来进一步自定义该特定端点的计时器。
- 在有
longTask = true
的方法上,为该方法启用长任务计时器。长任务计时器需要单独的度量名称,并且可以使用短任务计时器进行堆叠。
默认情况下,使用名为 http.server.requests
生成度量指标。可以通过设置 management.metrics.web.server.requests-metric-name
属性来自定义名称。
默认情况下,Jersey 服务器指标使用以下标签标记:
标签 | 描述 |
---|---|
exception |
处理请求时抛出的异常的简单类名。 |
method |
请求的方法(例如,GET 或 POST ) |
outcome |
根据响应状态码生成的请求结果。1xx 是 INFORMATIONAL ,2xx 是 SUCCESS ,3xx 是 REDIRECTION ,4xx 是 CLIENT_ERROR ,5xx 是 SERVER_ERROR |
status |
响应的 HTTP 状态码(例如,200 或 500 ) |
uri |
如果可能,在变量替换之前请求 URI 模板(例如,/api/person/{id} ) |
要自定义标签,请提供一个实现了 JerseyTagsProvider
的 @Bean
。
57.3.4、HTTP Client 指标
Spring Boot Actuator 管理 RestTemplate 和 WebClient 的指标记录。为此,你必须注入一个自动配置的 builder 并使用它来创建实例:
RestTemplateBuilder
用于RestTemplate
WebClient.Builder
用于WebClient
也可以手动指定负责此指标记录的自定义程序,即 MetricsRestTemplateCustomizer
和 MetricsWebClientCustomizer
。
默认情况下,使用名为 http.client.requests
生成度量指标。可以通过设置 management.metrics.web.client.requests-metric-name
属性来自定义名称。
默认情况下,已指标记录客户端生成的度量指标使用以下标签标记:
method
,请求的方法(例如,GET
或POST
)。uri
,变量替换之前的请求 URI 模板(如果可能)(例如,/api/person/{id}
)。status
,响应的 HTTP 状态码(例如,200
或500
)。clientName
,URI 的主机部分 。
要根据你选择的客户端自定义标签,你可以提供一个实现了 RestTemplateExchangeTagsProvider
或 WebClientExchangeTagsProvider
的 @Bean
。RestTemplateExchangeTags
和 WebClientExchangeTags
中有便捷的静态函数。
57.3.5、Cache 指标
在启动时,自动配置启动所有可用 Cache
的指标记录功能,指标以 cache
为前缀。缓存指标记录针对一组基本指标进行了标准化。此外,还提供了缓存特定的指标。
支持以下缓存库:
- Caffeine
- EhCache 2
- Hazelcast
- 所有兼容 JCache(JSR-107)的实现
度量指标由缓存的名称和从 bean 名称派生的 CacheManager
的名称标记。
注意
只有启动时可用的缓存才会绑定到注册表。对于在启动阶段之后即时或以编程方式创建的缓存,需要显式注册。可用
CacheMetricsRegistrar
bean 简化该过程。
57.3.6、数据源指标
自动配置启用对所有可用 DataSource
对象进行指标记录功能,指标的名称为 jdbc
。数据源指标记录会生成表示池中当前活动、大允许和最小允许连接的计量器(gauge)。这些计量器都有一个以 jdbc
为前缀的名称。
度量指标也由基于 bean 名称计算的 DataSource
的名称标记。
提示
默认情况下,Spring Boot 为所有支持的数据源提供了元数据。如果开箱即用不支持你喜欢的数据源,则可以添加其他
DataSourcePoolMetadataProvider
bean。有关示例,请参阅DataSourcePoolMetadataProvidersConfiguration
。
此外,Hikari 特定的指标用 hikaricp
前缀暴露。每个度量指标都由池名称标记(可以使用 spring.datasource.name
控制)。
57.3.7、Hibernate 指标
自动配置启用所有可用 Hibernate EntityManagerFactory
实例的指标记录功能,这些实例使用名为 hibernate
的度量指标统计信息。
度量指标也由从 bean 名称派生的 EntityManagerFactory
的名称标记。
要启用信息统计,必须将标准 JPA 属性 hibernate.generate_statistics
设置为 true
。你可以在自动配置的 EntityManagerFactory
上启用它,如下所示:
spring.jpa.properties.hibernate.generate_statistics=true
57.3.8、RabbitMQ 指标
自动配置将使用名为 rabbitmq
的度量指标启用对所有可用 RabbitMQ 连接工厂进行指标记录。
57.4、注册自定义指标
要注册自定义指标,请将 MeterRegistry
注入你的组件中,如下所示:
class Dictionary {
private final List<String> words = new CopyOnWriteArrayList<>();
Dictionary(MeterRegistry registry) {
registry.gaugeCollectionSize("dictionary.size", Tags.empty(), this.words);
}
// …
}
如果你发现跨组件或应用程序重复记录一套度量指标,则可以将此套件封装在 MeterBinder
实现中。默认情况下,所有 MeterBinder
bean 的指标都将自动绑定到 Spring 管理的 MeterRegistry
。
57.5、自定义单独指标
如果需要将自定义特定的 Meter
实例,可以使用 io.micrometer.core.instrument.config.MeterFilter
接口。默认情况下,所有 MeterFilter
bean 都将自动应用于 MeterRegistry.Config
。
例如,如果要将 mytag.region
标记重命名为 mytag.area
以获取以 com.example
开头的所有 meter ID,则可以执行以下操作:
@Bean
public MeterFilter renameRegionTagMeterFilter() {
return MeterFilter.renameTag("com.example", "mytag.region", "mytag.area");
}
57.5.1、自定义标签
通用标签通常用于操作环境中的维度下钻,例如主机、实例、区域、堆栈等。通用标签应用于所有 meter,并且可以按照以下示例进行配置:
management.metrics.tags.region=us-east-1
management.metrics.tags.stack=prod
上面的示例将 region
和 stack
标签添加到所有 meter 中,其值分别为 us-east-1
和 prod
。
注意
如果你使用 Graphite,那么标签的顺序很重要。由于使用此方法无法保证通用标签的顺序,因此建议 Graphite 用户定义自定义
MeterFilter
。
57.5.2、Per-meter 属性
除了 MeterFilter
bean 之外,还可以使用 properties 在 per-meter 基础上自定义。Per-meter 定义适用于以给定名称开头的所有 meter ID。例如,以下将禁用任何以 example.remote
开头的 ID 的 meter:
management.metrics.enable.example.remote=false
以下属性允许 per-meter 自定义:
表 57.1、Per-meter 自定义
| 属性 | 描述 || management.metrics.enable
| 是否拒绝 meter 发布任何指标。 || management.metrics.distribution.percentiles-histogram
| 是否发布一个适用于计算可聚合(跨维度)的百分比近似柱状图。 || management.metrics.distribution.minimum-expected-value
, management.metrics.distribution.maximum-expected-value
| 通过限制预期值的范围来发布较少的柱状图桶。 || management.metrics.distribution.percentiles
| 发布在你自己的应用程序中计算的百分比数值 || management.metrics.distribution.sla
| 发一个使用 SLA 定义的存储桶发布累积柱状图。 |
有关 percentiles-histogram
、percentiles
和 sla
概念的更多详细信息,请参阅「柱状图与百分位数」部分的文档。
57.6、指标端点
Spring Boot 提供了一个 metrics
端点,可以在诊断中用于检查应用程序收集的度量指标。默认情况下端点不可用,必须手动暴露,请参阅暴露端点以获取更多详细信息。
访问 /actuator/metrics
会显示可用的 meter 名称列表。你可以查看某一个 meter 的信息,方法是将其名称作为选择器,例如,/actuator/metrics/jvm.memory.max
。
提示
你在此处使用的名称应与代码中使用的名称相匹配,而不是在命名约定规范化后的名称 —— 为了发送到监控系统。换句话说,如果
jvm.memory.max
由于 Prometheus 命名约定而显示为jvm_memory_max
,则在审查度量指标端点中的 meter 时,应仍使用jvm.memory.max
作为选择器。
你还可以在 URL 的末尾添加任意数量的 tag=KEY:VALUE
查询参数,以便多维度向下钻取 meter,例如 /actuator/metrics/jvm.memory.max?tag=area:nonheap
。
提示
报告的测量值是与 meter 名称和已应用的任何标签匹配的所有 meter 的统计数据的总和。因此,在上面的示例中,返回的 Value 统计信息是堆的 Code Cache,Compressed Class Space 和 Metaspace 区域的最大内存占用量的总和。如果你只想查看 Metaspace 的最大大小,可以添加一个额外的 tag=id:Metaspace
,即 /actuator/metrics/jvm.memory.max?tag=area:nonheap&tag=id:Metaspace
。