对于最新稳定版本,请使用Spring Framework 7.0.1spring-doc.cadn.net.cn

可观测性支持

千米定义了一种观测概念,使得在应用中既能实现度量也支持痕迹。 度量支持提供了一种方法,可以创建计时器、计量器或计数器,以收集关于应用运行时行为的统计数据。 指标可以帮助你跟踪错误率、使用模式、性能等。 Traces提供了整个系统的整体视图,跨越应用边界;你可以放大特定用户请求,跟踪他们在整个应用中的完成过程。spring-doc.cadn.net.cn

Spring Framework 会对其代码库的各个部分进行仪器化,以便在观测登记册已配置。 你可以在 Spring Boot 中了解更多关于配置可观察性基础设施的信息。spring-doc.cadn.net.cn

已制作的观测列表

Spring Framework 为多种功能提供了可观测性工具。 如本节开头所述,观测值可根据配置生成计时器度量和/或追踪。spring-doc.cadn.net.cn

表1。春季框架产生的观测数据
观测名称 描述

“http.client.requests”spring-doc.cadn.net.cn

用于HTTP客户端交换的时间spring-doc.cadn.net.cn

“http.server.requests”spring-doc.cadn.net.cn

框架层面的HTTP服务器交换处理时间spring-doc.cadn.net.cn

观测数据采用Micrometer官方命名规范,但指标名称将自动转换为监测系统后端偏好的格式(Prometheus、Atlas、Graphite、InfluxDB等)。

微米观测概念

如果你不熟悉微米观测,这里有一个你应该了解的概念简要总结。spring-doc.cadn.net.cn

  • 观察是你申请中实际发生的事情的记录。该过程由观察处理器实现以产生指标或痕迹。spring-doc.cadn.net.cn

  • 每个观测值都有对应的观察背景实现;该类型包含提取元数据的所有相关信息。 对于HTTP服务器观察,上下文实现可以保存HTTP请求、HTTP响应、处理过程中抛出的任何异常等。spring-doc.cadn.net.cn

  • 观察保持关键值元数据。对于HTTP服务器的观察,这可以是HTTP请求方法、HTTP响应状态等。 本元数据由以下机构提供观察大会应声明 的实现观察背景他们支持。spring-doc.cadn.net.cn

  • 关键值如果存在一个低且有界的可能值,则称为“低基数”关键值元组(HTTP 方法是一个很好的例子)。 低基数值仅贡献给度量。 相反,“高基数”值是无界的(例如HTTP请求URI),仅贡献于痕迹。spring-doc.cadn.net.cn

  • 观察记录记录特定域内的所有观察,列出预期的关键名称及其含义。spring-doc.cadn.net.cn

观测值配置

全局配置选项可在观察登记册#观察配置()水平。 每个仪器化组件将提供两个扩展点:spring-doc.cadn.net.cn

使用自定义观测约定

我们以 Spring MVC “http.server.requests” 度量测量为例,其中ServerHttpObservationFilter. 此观察使用了一个ServerRequestObservationConvention其中Server请求观察上下文;Servlet 过滤器可以配置自定义约定。 如果你想自定义观测产生的元数据,可以扩展DefaultServerRequestObservationConvention满足您的需求:spring-doc.cadn.net.cn

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());
	}

}

如果你想要完全控制权,可以为你感兴趣的观察实现整个大会合同:spring-doc.cadn.net.cn

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– 为观察添加或删除关键值。 过滤器不替代默认惯例,而是作为后处理组件使用。spring-doc.cadn.net.cn

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实例观测登记册.spring-doc.cadn.net.cn

HTTP 服务器仪表

HTTP 服务器交换观测值以 命名为“http.server.requests”适用于Servlet和响应式应用。spring-doc.cadn.net.cn

Servlet 应用

应用程序需要配置org.springframework.web.filter.ServerHttpObservationFilter在他们的应用中使用了ServletFilter。 它使用org.springframework.http.server.observation.DefaultServerRequestObservationConvention默认情况下,支持者是Server请求观察上下文.spring-doc.cadn.net.cn

这只会在例外未被 Web 框架处理,已进入 Servlet 过滤器。 通常,所有异常都由 Spring MVC 处理@ExceptionHandler问题详情支持不会随观测记录。 在请求处理过程中,你可以在任何时刻设置错误字段观察背景你自己:spring-doc.cadn.net.cn

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创作;这超出了本项目的范围。

默认情况下,以下内容关键值创建了:spring-doc.cadn.net.cn

表2。低基数密钥

例外 (必填)spring-doc.cadn.net.cn

交换过程中抛出的异常名称,或关键值#NONE_VALUE} 如果没有例外发生。spring-doc.cadn.net.cn

方法 (必填)spring-doc.cadn.net.cn

HTTP 请求方法的名称或“没有”如果不是知名的方法。spring-doc.cadn.net.cn

结果 (必填)spring-doc.cadn.net.cn

HTTP服务器交换的结果。spring-doc.cadn.net.cn

地位 (必填)spring-doc.cadn.net.cn

HTTP 响应的原始状态码,或“未知”如果没有回应。spring-doc.cadn.net.cn

乌里 (必填)spring-doc.cadn.net.cn

如果有匹配处理器的URI模式,退回到重定向对于3xx个回复,NOT_FOUND共有404条回复,对于没有路径信息的请求,未知其他所有请求。spring-doc.cadn.net.cn

表3。高基数密钥

http.URL (必填)spring-doc.cadn.net.cn

HTTP 请求 URI。spring-doc.cadn.net.cn

响应式应用

应用程序需要配置org.springframework.web.filter.reactive.ServerHttpObservationFilter反应性的WebFilter在他们的申请中。 它使用org.springframework.http.server.reactive.observation.DefaultServerRequestObservationConvention默认情况下,支持者是Server请求观察上下文.spring-doc.cadn.net.cn

这只会在例外未被Web框架处理,已浮现至......WebFilter. 通常,所有例外情况都由 Spring WebFlux 处理@ExceptionHandler问题详情支持不会随观测记录。 在请求处理过程中,你可以在任何时刻设置错误字段观察背景你自己:spring-doc.cadn.net.cn

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 {
	}

}

默认情况下,以下内容关键值创建了:spring-doc.cadn.net.cn

表4。低基数密钥

例外 (必填)spring-doc.cadn.net.cn

交换过程中抛出的异常名称,或“没有”如果没有例外。spring-doc.cadn.net.cn

方法 (必填)spring-doc.cadn.net.cn

HTTP 请求方法的名称或“没有”如果不是知名的方法。spring-doc.cadn.net.cn

结果 (必填)spring-doc.cadn.net.cn

HTTP服务器交换的结果。spring-doc.cadn.net.cn

地位 (必填)spring-doc.cadn.net.cn

HTTP 响应的原始状态码,或“未知”如果没有回应。spring-doc.cadn.net.cn

乌里 (必填)spring-doc.cadn.net.cn

如果有匹配处理器的URI模式,退回到重定向对于3xx个回复,NOT_FOUND共有404条回复,对于没有路径信息的请求,未知其他所有请求。spring-doc.cadn.net.cn

表5。高基数密钥

http.URL (必填)spring-doc.cadn.net.cn

HTTP 请求 URI。spring-doc.cadn.net.cn

HTTP 客户端监测

HTTP 客户端交换观察值以 命名为“http.client.requests”针对阻断和反应型客户。 与服务器端不同,这些仪器直接在客户端实现,因此只需配置观测登记册在客户端。spring-doc.cadn.net.cn

Rest模板

应用程序必须配置观测登记册Rest模板实例以启用仪器;没有这些,观测值就是“无效行动”。 Spring Boot 会自动配置Rest模板构建器豆子已经设定好观察登记。spring-doc.cadn.net.cn

配器使用org.springframework.http.client.observation.ClientRequestObservationConvention默认情况下,支持者是客户端请求观察上下文.spring-doc.cadn.net.cn

表6。低基数密钥

方法 (必填)spring-doc.cadn.net.cn

HTTP 请求方法的名称或“没有”如果不是知名的方法。spring-doc.cadn.net.cn

乌里 (必填)spring-doc.cadn.net.cn

用于HTTP请求的URI模板,或“没有”如果没有提供。只考虑URI的路径部分。spring-doc.cadn.net.cn

client.name (必填)spring-doc.cadn.net.cn

客户端名称源自请求的URI主机。spring-doc.cadn.net.cn

地位 (必填)spring-doc.cadn.net.cn

HTTP 响应的原始状态码,或“IO_ERROR”IOException“CLIENT_ERROR”如果没有收到回复。spring-doc.cadn.net.cn

结果 (必填)spring-doc.cadn.net.cn

HTTP 客户端交换的结果。spring-doc.cadn.net.cn

例外 (必填)spring-doc.cadn.net.cn

交换过程中抛出的异常名称,或“没有”如果没有例外。spring-doc.cadn.net.cn

表7。高基数密钥

http.URL (必填)spring-doc.cadn.net.cn

HTTP 请求 URI。spring-doc.cadn.net.cn

Web客户端

应用程序必须配置观测登记册Web客户端建造器以实现仪器;没有这些,观测值就是“无效行动”。 Spring Boot 会自动配置WebClient.Builder豆子已经设定好观察登记。spring-doc.cadn.net.cn

配器使用org.springframework.web.reactive.function.client.ClientRequestObservationConvention默认情况下,支持者是客户端请求观察上下文.spring-doc.cadn.net.cn

表8。低基数密钥

方法 (必填)spring-doc.cadn.net.cn

HTTP 请求方法的名称或“没有”如果不是知名的方法。spring-doc.cadn.net.cn

乌里 (必填)spring-doc.cadn.net.cn

用于HTTP请求的URI模板,或“没有”如果没有提供。只考虑URI的路径部分。spring-doc.cadn.net.cn

client.name (必填)spring-doc.cadn.net.cn

客户端名称源自请求的URI主机。spring-doc.cadn.net.cn

地位 (必填)spring-doc.cadn.net.cn

HTTP 响应的原始状态码,或“IO_ERROR”IOException“CLIENT_ERROR”如果没有收到回复。spring-doc.cadn.net.cn

结果 (必填)spring-doc.cadn.net.cn

HTTP 客户端交换的结果。spring-doc.cadn.net.cn

例外 (必填)spring-doc.cadn.net.cn

交换过程中抛出的异常名称,或“没有”如果没有例外。spring-doc.cadn.net.cn

表9。高基数密钥

http.URL (必填)spring-doc.cadn.net.cn

HTTP 请求 URI。spring-doc.cadn.net.cn