Micrometer 系列【56】统一观测:扩展接口 | ObservationPredicate、ObservationFilter
文章目录1. 概述1.1 基础定义1.2 核心特征1.3 工作原理1创建阶段2启动观测3执行业务逻辑4观测结束2. 源码分析2.1 ObservationPredicate观测断言接口2.2 ObservationFilter上下文过滤器接口2.3 PropertiesObservationFilterPredicateSpring Boot 内置融合实现3. 完整示例3.1 自定义观测 Predicate3.2 自定义观测 Filter3.3 自定义观测处理器 业务服务类3.4 程序入口1. 概述框架提供两大扩展接口ObservationPredicate用于全局动态控制观测是否创建实现降噪、屏蔽低价值观测ObservationFilter在观测停止阶段修改上下文补充运行时、后置数据标签。Spring Boot、Spring AI等主流组件大量基于这两个接口实现配置化开关、全局公共标签、动态追加业务高基数字段。本文基于原生源码讲解接口定义、运行机制、源码细节以及完整可运行示例。1.1 基础定义ObservationPredicate继承BiPredicateString, 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 ObservationSpring Boot自动将容器内所有ObservationPredicateBean注册到ObservationRegistry典型实现PropertiesObservationFilterPredicate读取配置文件按观测名称前缀控制开关支持层级匹配http.server匹配http.server.request。publicinterfaceObservationPredicateextendsBiPredicateString,Observation.Context{}2.2 ObservationFilter上下文过滤器接口唯一方法map()接收可变Context支持修改、追加标签返回处理后的上下文执行时机固定stop()内部、onStop回调之前典型场景Spring Boot统一注入全局公共低基数标签环境、应用名称Spring AIToolCallingContentObservationFilter业务执行结束后追加工具入参、返回结果等高基数标签支持多Filter链式调用前一个Filter返回的上下文作为下一个Filter的入参。publicinterfaceObservationFilter{Observation.Contextmap(Observation.Contextcontext);}2.3 PropertiesObservationFilterPredicateSpring 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_NAMEorder-service;OverridepublicObservation.Contextmap(Observation.Contextcontext){// 统一增加全局低基数标签context.addLowCardinalityKeyValue(KeyValue.of(application,APP_NAME));// 如果存在异常追加错误类型标签Throwableerrorcontext.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){ObservationRegistryregistryObservationRegistry.create();// 注册Predicate全局观测断言registry.observationConfig().observationPredicate(newNoiseObservationPredicate());// 注册Filter全局上下文过滤器registry.observationConfig().observationFilter(newGlobalCommonObservationFilter());// 注册自定义处理器registry.observationConfig().observationHandler(newDebugLogObservationHandler());OrderBizServiceservicenewOrderBizService(registry);// 正常业务观测service.createOrder(OD20260813_002);// 健康检查被Predicate拦截无日志输出service.healthCheck();}}