我想用AOP实现一个日志记录概念,但打印日志时我需要给我自己的方法名称而不是默认值。在Logback中覆盖方法名称(%M转换说明符)
更新(基于@glitch评论):
我使用
%M
转换符告诉的logback包括在每个日志事件的方法名称。我想回报某些 logback派生方法名称spicifically;用于由我的AOP连接点发出的日志事件。
我不想在日志事件的其他地方写'实际方法名'我想要使用的方法名称是正确的,即表示原始方法而不是拦截方法。
我想用AOP实现一个日志记录概念,但打印日志时我需要给我自己的方法名称而不是默认值。在Logback中覆盖方法名称(%M转换说明符)
更新(基于@glitch评论):
我使用%M
转换符告诉的logback包括在每个日志事件的方法名称。
我想回报某些 logback派生方法名称spicifically;用于由我的AOP连接点发出的日志事件。
我不想在日志事件的其他地方写'实际方法名'我想要使用的方法名称是正确的,即表示原始方法而不是拦截方法。
%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
的静态初始化器中声明,并且这不可扩展/可覆盖。所以,我觉得你的选择是:
在自己的代码库,即用自己的logback取代自己MethodOfCallerConverter创建ch.qos.logback.classic.pattern.MethodOfCallerConverter
类。您可以使用的例子,我的上方,并 - 只要你把MDC的CUSTOM_METHOD_NAME_KEY
值调用的记录之前 - 它会做你想要什么
继续使用%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
停止使用%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
谢谢你是一个天才,现在一切都像一个cham –
由于Logback提供没有注册自己的'%M'转换说明符的钩子,你'扩展'通过模仿它的'MethodOfCallerConverter'进行Logback。这种方法有效,但它不是标准的,可能很脆弱;如果未来的Logback版本更改了“MethodOfCallerConverter”的名称或命名空间,那么您也必须更改“MethodOfCallerConverter”的版本。只是要记住一些事情.... – glytching
你指的“默认”,这是否意味着你使用的是'%M'转换说明在你的logback模式让的logback推导方法的名字吗?您是否想将其替换为所有日志事件或仅针对选定的日志事件?是否必须替换它,或者在日志消息的其他位置写入其他方法名称是否足够? – glytching
我在两种方式使用日志记录,一种是正常的日志记录方法和aspectj AOP。对于正常的日志记录方法名称是正确打印,但对于最终的Logger logger = LoggerFactory.getLogger(pjp.getSignature()。getDeclaringTypeName());这个记录器打印aop方法而不是确切的方法,我使用'ProceedingJoinPoint' –
在这里我可以得到确切的方法名称与pjp.getSignature()。getName(),但记录器需要打印此方法名称而不是aop方法名称,如果这不是possbile我可以用这个方法名称覆盖%M –