You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中如何扩展SLF4J实现统一统计ERROR日志的Micrometer计数器

实现SLF4J ERROR日志统一统计Micrometer计数器(Spring Bean版)

完全可以实现这个需求,下面是基于Spring Boot+Logback(SLF4J默认实现)的具体方案,能让自定义日志拦截逻辑成为Spring管理的Bean,自动注入Micrometer组件,统一统计ERROR级别的异常日志:

1. 自定义Logback TurboFilter(日志拦截器)

TurboFilter是Logback提供的全局日志拦截扩展点,能在日志事件处理前执行逻辑,适合做统一统计。我们将它实现为Spring Bean,直接注入Micrometer的MeterRegistry:

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.turbo.TurboFilter;
import ch.qos.logback.core.spi.FilterReply;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import org.slf4j.Marker;
import org.springframework.stereotype.Component;

@Component
public class ErrorLogMetricFilter extends TurboFilter {

    private final Counter errorExceptionCounter;

    // 构造注入Spring管理的MeterRegistry
    public ErrorLogMetricFilter(MeterRegistry meterRegistry) {
        // 定义计数器,可根据需求添加标签(比如异常类型、日志类名)
        this.errorExceptionCounter = meterRegistry.counter(
            "application.errors.total",
            "type", "unhandled_exception"
        );
    }

    @Override
    public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
        // 仅统计带有异常的ERROR级别日志(若需所有ERROR日志,去掉t != null判断)
        if (Level.ERROR.equals(level) && t != null) {
            // 可选:按异常类型细分标签
            // meterRegistry.counter("application.errors.total", "exception", t.getClass().getSimpleName()).increment();
            errorExceptionCounter.increment();
        }
        // 放行日志,不影响原有日志输出流程
        return FilterReply.NEUTRAL;
    }
}

2. 将Filter注册到Logback上下文

由于Logback初始化早于Spring容器,需要在Spring启动完成后手动把自定义Filter注册到Logback的全局上下文:

import ch.qos.logback.classic.LoggerContext;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Component
public class LogbackFilterRegistrar {

    private final ErrorLogMetricFilter errorLogMetricFilter;

    @Autowired
    public LogbackFilterRegistrar(ErrorLogMetricFilter errorLogMetricFilter) {
        this.errorLogMetricFilter = errorLogMetricFilter;
    }

    @PostConstruct
    public void registerFilter() {
        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
        // 将自定义Filter添加到Logback全局上下文,确保生效
        loggerContext.addTurboFilter(errorLogMetricFilter);
    }
}

3. 优化与注意事项

  • 去重处理:删除原有catch块中手动添加的计数器代码,避免重复统计。
  • 标签扩展:可根据业务需求给计数器添加标签,比如异常类型、日志所属服务模块、环境等,方便Grafana多维度分析。
  • 性能保障:TurboFilter逻辑要尽量轻量,避免在拦截器中做IO或复杂计算,防止影响日志输出性能。
  • 适配其他SLF4J实现:若使用Log4j2而非Logback,可替换为Log4j2的AbstractFilter实现,注册方式调整为通过Log4j2的API添加过滤器。

内容的提问来源于stack exchange,提问作者zappee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 04:25:57