Spring Boot下@WebServlet接口Micrometer监控指标uri为UNKNOWN问题求助
问题原因
Spring Boot默认集成的Micrometer HTTP服务指标采集逻辑,依赖Spring MVC的映射体系获取请求的URI模板。你通过@WebServlet注册的自定义Servlet不属于Spring MVC的@RequestMapping端点体系,Micrometer的采集过滤器无法识别你定义的路径模板/api/service/*。为了避免动态路径导致的指标基数爆炸,采集逻辑会直接将uri字段赋值为UNKNOWN。
修复方案
有两种轻量修复方案可选:
方案1:直接在Servlet代码中设置URI模板属性
在service方法入口处,向请求对象写入Micrometer可识别的URI模板属性即可,兼容Spring Boot 2.x和3.x版本:
@Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { // 新增以下代码 if (servletRequest instanceof HttpServletRequest httpReq) { // 适配Spring Boot 2.x Micrometer指标采集 httpReq.setAttribute("org.springframework.web.servlet.HandlerMapping.bestMatchingPattern", "/api/service/*"); // 适配Spring Boot 3.x可观测性采集 httpReq.setAttribute("org.springframework.web.filter.ServerHttpObservationFilter.lookupPath", "/api/service/*"); } Map<String, String[]> parameterMap = servletRequest.getParameterMap(); log.info("sumit {}", parameterMap); }
方案2:新增全局Filter统一处理
如果不想修改原有Servlet代码,可以新增一个高优先级的Filter,匹配到对应路径时自动注入URI模板属性:
- 新增Filter类:
@WebFilter(urlPatterns = "/api/service/*") @Order(Ordered.HIGHEST_PRECEDENCE + 1) // 保证优先级高于Micrometer的采集过滤器 public class MetricsUriPatchFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (request instanceof HttpServletRequest httpReq) { httpReq.setAttribute("org.springframework.web.servlet.HandlerMapping.bestMatchingPattern", "/api/service/*"); httpReq.setAttribute("org.springframework.web.filter.ServerHttpObservationFilter.lookupPath", "/api/service/*"); } chain.doFilter(request, response); } }
- 确保启动类添加了
@ServletComponentScan注解,能扫描到你定义的@WebServlet和@WebFilter。
修复完成后重新请求接口,即可看到指标中uri字段显示为/api/service/*,不再是UNKNOWN。
内容的提问来源于stack exchange,提问作者SUMIT
相关产品推荐
相关产品推荐

