文章目录
- 1. 概述
- 1.1 基础定义
- 1.2 核心特征
- 1.3 工作原理
- (1)创建阶段
- (2)启动观测
- (3)执行业务逻辑
- (4)观测结束
- 2. 源码分析
- 2.1 ObservationPredicate:观测断言接口
- 2.2 ObservationFilter:上下文过滤器接口
- 2.3 PropertiesObservationFilterPredicate:Spring Boot 内置融合实现
- 3. 完整示例
- 3.1 自定义观测 Predicate
- 3.2 自定义观测 Filter
- 3.3 自定义观测处理器 & 业务服务类
- 3.4 程序入口
1. 概述
框架提供两大扩展接口:
ObservationPredicate用于全局动态控制观测是否创建,实现降噪、屏蔽低价值观测;ObservationFilter在观测停止阶段修改上下文,补充运行时、后置数据标签。
Spring Boot、Spring AI等主流组件大量基于这两个接口实现配置化开关、全局公共标签、动态追加业务高基数字段。本文基于原生源码,讲解接口定义、运行机制、源码细节以及完整可运行示例。
1.1 基础定义
ObservationPredicate:继承BiPredicate<String, Observation.Context>,观测创建阶段执行判断,返回false则生成No-op Observation,不会触发任何ObservationHandler,无性能开销。
入参:观测名称name、观测上下文Context。
ObservationFilter:提供map(Context context)回调,在观测stop()阶段、所有ObservationHandler执行之前修改上下文对象,支持追加标签、填充后置数据。
关键时序:Filter在业务执行完成之后、处理器采集数据之前执行,适合获取返回结果、异常信息、响应内容。
与已有组件简单区分
ObservationConvention:绑定单个Observation实例,定义观测名称、从上下文提取标签;ObservationPredicate:全局开关,决定本次观测要不要创建;ObservationFilter:全局过滤器,统一修改上下文、补充标签;ObservationHandler:最终消费上下文,生成指标、Span。
1.2 核心特征
- 全局生效机制:向
ObservationRegistry注册后,对应用内所有Observation统一生效,无需改造业务埋点代码。 - 执行时序严格隔离
Predicate:观测创建阶段执行,早于start();Filter:观测停止阶段执行,晚于业务逻辑、早于onStop()处理器。
- 性能友好降噪:
Predicate返回false直接返回空实现No-op Observation,避免上下文创建、处理器回调等开销,适合屏蔽健康检查、轮询等噪声观测。 - 后置数据填充能力:
Filter在stop阶段执行,可以拿到业务执行完成后的响应、异常对象,非常适合追加结果类高基数标签。 - 多实例叠加:支持注册多个
Predicate、多个Filter;多个Predicate需要全部返回 true才创建观测;多个Filter按注册顺序链式处理上下文。
1.3 工作原理
完整生命周期跟随Observation创建、启动、业务执行、停止全流程。
(1)创建阶段
调用Observation.createNotStarted():
- 框架收集所有注册的
ObservationPredicate; - 依次执行
test(name, context); - 任意一个
Predicate返回false,直接返回No-op Observation,后续流程全部跳过; - 全部
Predicate返回true,创建真实Observation对象。
⚠️
Predicate执行时业务尚未运行,无法获取响应、异常等运行时信息。
(2)启动观测
执行observation.start(),分发onStart回调;Predicate、Filter 均不会在此阶段触发。
(3)执行业务逻辑
执行observe()内部业务代码;上下文可以持续写入业务数据;此阶段Predicate、Filter不执行。
(4)观测结束
调用observation.stop():
- 遍历所有注册
ObservationFilter,依次执行map(context),链式修改上下文; - 使用修改完成后的上下文,逆序执行所有
ObservationHandler#onStop(); - 指标、链路采集基于
Filter修改后的上下文完成。
2. 源码分析
2.1 ObservationPredicate:观测断言接口
- 继承
JDK标准BiPredicate,接收观测名称、上下文两个参数; - 返回
true:创建正常Observation;返回false:创建No-op Observation; Spring Boot自动将容器内所有ObservationPredicateBean注册到ObservationRegistry;- 典型实现:
PropertiesObservationFilterPredicate,读取配置文件,按观测名称前缀控制开关,支持层级匹配(http.server匹配http.server.request)。
publicinterfaceObservationPredicateextendsBiPredicate<String,Observation.Context>{}2.2 ObservationFilter:上下文过滤器接口
- 唯一方法
map(),接收可变Context,支持修改、追加标签,返回处理后的上下文; - 执行时机固定:
stop()内部、onStop回调之前; - 典型场景:
Spring Boot:统一注入全局公共低基数标签(环境、应用名称);Spring AI:ToolCallingContentObservationFilter,业务执行结束后追加工具入参、返回结果等高基数标签;
- 支持多
Filter链式调用,前一个Filter返回的上下文作为下一个Filter的入参。
publicinterfaceObservationFilter{Observation.Contextmap(Observation.Contextcontext);}2.3 PropertiesObservationFilterPredicate:Spring Boot 内置融合实现
- 同时实现
Predicate、Filter两个接口; Predicate能力:读取management.observations.enable.*配置,控制各类观测开关;Filter能力:读取全局公共标签配置,统一为所有观测追加固定KeyValues;- 体现框架设计思路:同一类配置逻辑,可以同时管控观测启停与上下文统一增强。
classPropertiesObservationFilterPredicateimplementsObservationFilter,ObservationPredicate{}3. 完整示例
场景:纯原生Java,无Spring;
- 自定义
ObservationPredicate:屏蔽健康检查类噪声观测; - 自定义
ObservationFilter:全局统一追加应用名称标签,同时捕获异常填充错误类型; - 业务埋点包含正常订单观测、健康检查观测(会被
Predicate过滤)。
3.1 自定义观测 Predicate
噪声观测过滤器,屏蔽健康检查观测,减少监控数据量:
publicclassNoiseObservationPredicateimplementsObservationPredicate{@Overridepublicbooleantest(StringobservationName,Observation.Contextcontext){// 健康检查类观测直接禁用,返回false生成No-opif("health.check".equals(observationName)){returnfalse;}returntrue;}}3.2 自定义观测 Filter
所有观测统一追加公共标签,补充异常信息标签,全局观测过滤器:
publicclassGlobalCommonObservationFilterimplementsObservationFilter{privatestaticfinalStringAPP_NAME="order-service";@OverridepublicObservation.Contextmap(Observation.Contextcontext){// 统一增加全局低基数标签context.addLowCardinalityKeyValue(KeyValue.of("application",APP_NAME));// 如果存在异常,追加错误类型标签Throwableerror=context.getError();if(error!=null){context.addLowCardinalityKeyValue(KeyValue.of("error.type",error.getClass().getSimpleName()));}returncontext;}}3.3 自定义观测处理器 & 业务服务类
同上一篇,不再赘述!!!
3.4 程序入口
注册全局观测断言、全局上下文过滤器
importio.micrometer.observation.ObservationRegistry;publicclassObservationMain{publicstaticvoidmain(String[]args){ObservationRegistryregistry=ObservationRegistry.create();// 注册Predicate:全局观测断言registry.observationConfig().observationPredicate(newNoiseObservationPredicate());// 注册Filter:全局上下文过滤器registry.observationConfig().observationFilter(newGlobalCommonObservationFilter());// 注册自定义处理器registry.observationConfig().observationHandler(newDebugLogObservationHandler());OrderBizServiceservice=newOrderBizService(registry);// 正常业务观测service.createOrder("OD20260813_002");// 健康检查,被Predicate拦截,无日志输出service.healthCheck();}}