如何覆盖 Logback 日志记录中的方法名称?

How to Override method name in Logback logging?

我正在尝试使用 AOP 实现日志记录概念,但是在打印日志时我需要提供我自己的方法名称而不是默认方法名称。

更新(基于@glitch 的评论):

%M 转换说明符由 ch.qos.logback.classic.pattern.MethodOfCallerConverter 实现。实现非常简单:

public String convert(ILoggingEvent le) {
    StackTraceElement[] cda = le.getCallerData();
    if (cda != null && cda.length > 0) {
        return cda[0].getMethodName();
    } else {
        return CallerData.NA;
    }
}

因此,您可以提供自己的实现。可能是这样的......

public class CustomMethodOfCallerConverter extends ClassicConverter {

    public String convert(ILoggingEvent le) {
        StackTraceElement[] cda = le.getCallerData();
        if (cda != null && cda.length > 0) {
            if (le.getMDCPropertyMap().containsKey("CUSTOM_METHOD_NAME_KEY")) {
                String methodName = le.getMDCPropertyMap().get("CUSTOM_METHOD_NAME_KEY");
                // remove the MDC entry since we are only using MDC to pass the custom method name into this converter
                le.getMDCPropertyMap().remove("CUSTOM_METHOD_NAME_KEY");
                return methodName;
            } else {
                return cda[0].getMethodName();
            }
        } else {
            return CallerData.NA;
        }
    }
}

... 它使用 MDC 从您的连接点传递实际的方法名称。在您的连接点中,您可以在调用记录器之前放置 MDC 值,例如

MDC.put("CUSTOM_METHOD_NAME_KEY", pjp.getSignature().getName()));

但是... Logback 不提供任何方式让您声明自己的自定义转换器。 Logback 使用的转换器在静态初始化程序中声明 ch.qos.logback.classic.PatternLayout 而这不是 extensible/overrideable。所以,我认为你的选择是:

  1. 在您自己的代码库中创建一个 ch.qos.logback.classic.pattern.MethodOfCallerConverter class,即将 Logback 自己的 MethodOfCallerConverter 替换为您自己的。您可以使用我上面提供的示例 - 只要您在调用记录器之前将 CUSTOM_METHOD_NAME_KEY 值放入 M​​DC - 它就会执行您想要的操作

  2. 继续使用 %M 说明符,但对于 AOP 拦截的方法添加一个额外的 MDC 属性以显示实际的方法名称。这将导致 Logback 方法名称出现在所有日志输出中,同时出现 actula 方法名称(如果可用)。例如:

    // put the actual method name in MDC
    MDC.put("actualMethodName", pjp.getSignature().getName());
    
    // specify your pattern - in logback.xml - to include the actual method name
    %d{yyyy-MM-dd HH:mm:ss}|[%thread]|%-5level|%logger{36}|%M%X{actualMethodName:-}|%msg%n
    
  3. 停止使用 %M 说明符并通过 MDC 记录所有方法名称。这会导致出现正确的方法名称,但它会要求您在每个方法中更新 MDC(这听起来很尴尬)。例如:

    // put the actual method name in MDC
    MDC.put("actualMethodName", pjp.getSignature().getName());
    
    // specify your pattern - in logback.xml - to include the actual method name
    %d{yyyy-MM-dd HH:mm:ss}|[%thread]|%-5level|%logger{36}|%X{actualMethodName}|%msg%n