|
对于最新稳定版本,请使用Spring Framework 7.0.1! |
可观测性支持
千米定义了一种观测概念,使得在应用中既能实现度量也支持痕迹。 度量支持提供了一种方法,可以创建计时器、计量器或计数器,以收集关于应用运行时行为的统计数据。 指标可以帮助你跟踪错误率、使用模式、性能等。 Traces提供了整个系统的整体视图,跨越应用边界;你可以放大特定用户请求,跟踪他们在整个应用中的完成过程。
Spring Framework 会对其代码库的各个部分进行仪器化,以便在观测登记册已配置。
你可以在 Spring Boot 中了解更多关于配置可观察性基础设施的信息。
已制作的观测列表
Spring Framework 为多种功能提供了可观测性工具。 如本节开头所述,观测值可根据配置生成计时器度量和/或追踪。
| 观测名称 | 描述 |
|---|---|
用于HTTP客户端交换的时间 |
|
框架层面的HTTP服务器交换处理时间 |
| 观测数据采用Micrometer官方命名规范,但指标名称将自动转换为监测系统后端偏好的格式(Prometheus、Atlas、Graphite、InfluxDB等)。 |
微米观测概念
如果你不熟悉微米观测,这里有一个你应该了解的概念简要总结。
-
观察是你申请中实际发生的事情的记录。该过程由观察处理器实现以产生指标或痕迹。 -
每个观测值都有对应的
观察背景实现;该类型包含提取元数据的所有相关信息。 对于HTTP服务器观察,上下文实现可以保存HTTP请求、HTTP响应、处理过程中抛出的任何异常等。 -
每
观察保持关键值元数据。对于HTTP服务器的观察,这可以是HTTP请求方法、HTTP响应状态等。 本元数据由以下机构提供观察大会应声明 的实现观察背景他们支持。 -
关键值如果存在一个低且有界的可能值,则称为“低基数”关键值元组(HTTP 方法是一个很好的例子)。 低基数值仅贡献给度量。 相反,“高基数”值是无界的(例如HTTP请求URI),仅贡献于痕迹。 -
一
观察记录记录特定域内的所有观察,列出预期的关键名称及其含义。
观测值配置
全局配置选项可在观察登记册#观察配置()水平。
每个仪器化组件将提供两个扩展点:
-
设置
观测登记册;如果未设置,观测数据不会被记录,将被视为无作 -
提供自定义
观察大会更改默认观测名称并提取关键值
使用自定义观测约定
我们以 Spring MVC “http.server.requests” 度量测量为例,其中ServerHttpObservationFilter.
此观察使用了一个ServerRequestObservationConvention其中Server请求观察上下文;Servlet 过滤器可以配置自定义约定。
如果你想自定义观测产生的元数据,可以扩展DefaultServerRequestObservationConvention满足您的需求:
import io.micrometer.common.KeyValue;
import io.micrometer.common.KeyValues;
import org.springframework.http.server.observation.DefaultServerRequestObservationConvention;
import org.springframework.http.server.observation.ServerRequestObservationContext;
public class ExtendedServerRequestObservationConvention extends DefaultServerRequestObservationConvention {
@Override
public KeyValues getLowCardinalityKeyValues(ServerRequestObservationContext context) {
// here, we just want to have an additional KeyValue to the observation, keeping the default values
return super.getLowCardinalityKeyValues(context).and(custom(context));
}
private KeyValue custom(ServerRequestObservationContext context) {
return KeyValue.of("custom.method", context.getCarrier().getMethod());
}
}
如果你想要完全控制权,可以为你感兴趣的观察实现整个大会合同:
import io.micrometer.common.KeyValue;
import io.micrometer.common.KeyValues;
import org.springframework.http.server.observation.ServerHttpObservationDocumentation;
import org.springframework.http.server.observation.ServerRequestObservationContext;
import org.springframework.http.server.observation.ServerRequestObservationConvention;
public class CustomServerRequestObservationConvention implements ServerRequestObservationConvention {
@Override
public String getName() {
// will be used as the metric name
return "http.server.requests";
}
@Override
public String getContextualName(ServerRequestObservationContext context) {
// will be used for the trace name
return "http " + context.getCarrier().getMethod().toLowerCase();
}
@Override
public KeyValues getLowCardinalityKeyValues(ServerRequestObservationContext context) {
return KeyValues.of(method(context), status(context), exception(context));
}
@Override
public KeyValues getHighCardinalityKeyValues(ServerRequestObservationContext context) {
return KeyValues.of(httpUrl(context));
}
private KeyValue method(ServerRequestObservationContext context) {
// You should reuse as much as possible the corresponding ObservationDocumentation for key names
return KeyValue.of(ServerHttpObservationDocumentation.LowCardinalityKeyNames.METHOD, context.getCarrier().getMethod());
}
// status(), exception(), httpUrl()...
private KeyValue status(ServerRequestObservationContext context) {
return KeyValue.of(ServerHttpObservationDocumentation.LowCardinalityKeyNames.STATUS, String.valueOf(context.getResponse().getStatus()));
}
private KeyValue exception(ServerRequestObservationContext context) {
String exception = (context.getError() != null) ? context.getError().getClass().getSimpleName() : KeyValue.NONE_VALUE;
return KeyValue.of(ServerHttpObservationDocumentation.LowCardinalityKeyNames.EXCEPTION, exception);
}
private KeyValue httpUrl(ServerRequestObservationContext context) {
return KeyValue.of(ServerHttpObservationDocumentation.HighCardinalityKeyNames.HTTP_URL, context.getCarrier().getRequestURI());
}
}
你也可以用自定义实现类似目标观察Filter– 为观察添加或删除关键值。
过滤器不替代默认惯例,而是作为后处理组件使用。
import io.micrometer.common.KeyValue;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationFilter;
import org.springframework.http.server.observation.ServerRequestObservationContext;
public class ServerRequestObservationFilter implements ObservationFilter {
@Override
public Observation.Context map(Observation.Context context) {
if (context instanceof ServerRequestObservationContext serverContext) {
context.setName("custom.observation.name");
context.addLowCardinalityKeyValue(KeyValue.of("project", "spring"));
String customAttribute = (String) serverContext.getCarrier().getAttribute("customAttribute");
context.addLowCardinalityKeyValue(KeyValue.of("custom.attribute", customAttribute));
}
return context;
}
}
你可以配置观察Filter实例观测登记册.
HTTP 服务器仪表
HTTP 服务器交换观测值以 命名为“http.server.requests”适用于Servlet和响应式应用。
Servlet 应用
应用程序需要配置org.springframework.web.filter.ServerHttpObservationFilter在他们的应用中使用了ServletFilter。
它使用org.springframework.http.server.observation.DefaultServerRequestObservationConvention默认情况下,支持者是Server请求观察上下文.
这只会在例外未被 Web 框架处理,已进入 Servlet 过滤器。
通常,所有异常都由 Spring MVC 处理@ExceptionHandler和问题详情支持不会随观测记录。
在请求处理过程中,你可以在任何时刻设置错误字段观察背景你自己:
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.filter.ServerHttpObservationFilter;
@Controller
public class UserController {
@ExceptionHandler(MissingUserException.class)
ResponseEntity<Void> handleMissingUser(HttpServletRequest request, MissingUserException exception) {
// We want to record this exception with the observation
ServerHttpObservationFilter.findObservationContext(request)
.ifPresent(context -> context.setError(exception));
return ResponseEntity.notFound().build();
}
static class MissingUserException extends RuntimeException {
}
}
由于仪器化是在ServletFilter层级完成的,观测范围仅涵盖之后订购的Filter以及请求的处理。
通常,Servlet 容器错误处理在较低层级执行,不会有主动观察或跨度。
对于此用例,需要一个容器特定的实现,例如org.apache.catalina.Valve为Tomcat创作;这超出了本项目的范围。 |
默认情况下,以下内容关键值创建了:
名称 |
描述 |
|
交换过程中抛出的异常名称,或 |
|
HTTP 请求方法的名称或 |
|
HTTP服务器交换的结果。 |
|
HTTP 响应的原始状态码,或 |
|
如果有匹配处理器的URI模式,退回到 |
名称 |
描述 |
|
HTTP 请求 URI。 |
响应式应用
应用程序需要配置org.springframework.web.filter.reactive.ServerHttpObservationFilter反应性的WebFilter在他们的申请中。
它使用org.springframework.http.server.reactive.observation.DefaultServerRequestObservationConvention默认情况下,支持者是Server请求观察上下文.
这只会在例外未被Web框架处理,已浮现至......WebFilter.
通常,所有例外情况都由 Spring WebFlux 处理@ExceptionHandler和问题详情支持不会随观测记录。
在请求处理过程中,你可以在任何时刻设置错误字段观察背景你自己:
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.filter.reactive.ServerHttpObservationFilter;
import org.springframework.web.server.ServerWebExchange;
@Controller
public class UserController {
@ExceptionHandler(MissingUserException.class)
ResponseEntity<Void> handleMissingUser(ServerWebExchange exchange, MissingUserException exception) {
// We want to record this exception with the observation
ServerHttpObservationFilter.findObservationContext(exchange)
.ifPresent(context -> context.setError(exception));
return ResponseEntity.notFound().build();
}
static class MissingUserException extends RuntimeException {
}
}
默认情况下,以下内容关键值创建了:
名称 |
描述 |
|
交换过程中抛出的异常名称,或 |
|
HTTP 请求方法的名称或 |
|
HTTP服务器交换的结果。 |
|
HTTP 响应的原始状态码,或 |
|
如果有匹配处理器的URI模式,退回到 |
名称 |
描述 |
|
HTTP 请求 URI。 |
HTTP 客户端监测
HTTP 客户端交换观察值以 命名为“http.client.requests”针对阻断和反应型客户。
与服务器端不同,这些仪器直接在客户端实现,因此只需配置观测登记册在客户端。
Rest模板
应用程序必须配置观测登记册上Rest模板实例以启用仪器;没有这些,观测值就是“无效行动”。
Spring Boot 会自动配置Rest模板构建器豆子已经设定好观察登记。
配器使用org.springframework.http.client.observation.ClientRequestObservationConvention默认情况下,支持者是客户端请求观察上下文.
名称 |
描述 |
|
HTTP 请求方法的名称或 |
|
用于HTTP请求的URI模板,或 |
|
客户端名称源自请求的URI主机。 |
|
HTTP 响应的原始状态码,或 |
|
HTTP 客户端交换的结果。 |
|
交换过程中抛出的异常名称,或 |
名称 |
描述 |
|
HTTP 请求 URI。 |
Web客户端
应用程序必须配置观测登记册在Web客户端建造器以实现仪器;没有这些,观测值就是“无效行动”。
Spring Boot 会自动配置WebClient.Builder豆子已经设定好观察登记。
配器使用org.springframework.web.reactive.function.client.ClientRequestObservationConvention默认情况下,支持者是客户端请求观察上下文.
名称 |
描述 |
|
HTTP 请求方法的名称或 |
|
用于HTTP请求的URI模板,或 |
|
客户端名称源自请求的URI主机。 |
|
HTTP 响应的原始状态码,或 |
|
HTTP 客户端交换的结果。 |
|
交换过程中抛出的异常名称,或 |
名称 |
描述 |
|
HTTP 请求 URI。 |