Java 使用EclipseApectJ注入一个日志记录器,记录执行代码的上下文/元数据?
我试图定义一个方面来注入记录器 我希望创建类似以下内容:Java 使用EclipseApectJ注入一个日志记录器,记录执行代码的上下文/元数据?,java,aop,aspectj,Java,Aop,Aspectj,我试图定义一个方面来注入记录器 我希望创建类似以下内容: import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public aspect LogInjector { private pointcut executionJoinPoints(): !within(LogInjector) && execution (* *.*(..)); bef
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public aspect LogInjector {
private pointcut executionJoinPoints(): !within(LogInjector) && execution (* *.*(..));
before(): executionJoinPoints(){
// Get class name of the executed code
clazz = ...
final Logger logger = LogManager.getLogger(clazz);
// Get method name of the executed code
method = ...
// Get params name, type and values triplet or values at least if the previous is not possible, of the executed code
params = ...
// Get call stack of the executed code
stack = ...
logger.trace("{}.{}({}) - {}", clazz.name(), method.name(), params, stack);
}
after(): executionJoinPoints(){
// Get class name of the executed code
clazz = ...
final Logger logger = LogManager.getLogger(clazz);
// Get method name of the executed code
method = ...
// Get return value or exception of the executed code
result = ...
logger.trace("{}.{} = {}", clazz.name(), method.name(), result);
}
}
为此,我希望检索执行元数据/上下文数据:
- 例外情况
- 返回值
如何获取此元数据/上下文数据?为了保持方面的效率,我建议您采取以下措施:
- 将切入点限制在您真正希望调试的目标包和类上。不要记录/追踪整个世界。您还可以使用带有抽象切入点的抽象基本方面,并将该方面扩展为带有具体切入点的具体子方面。如果使用加载时编织,则后者甚至可以通过XML配置提供
- 使用
建议,而不是around()
/before()
对。然后,只需计算一些记录的值一次,并在通过after()
完成原始方法调用之前和之后使用它们procedure()
- 只需记录此连接点,而不是默认情况下拼接其中包含的位。这已经为您提供了连接点的类型、方法签名,包括参数类型和返回值
- 不要记录参数名称,该信息不会增加实际值。此外,参数名要经过重构,并且只有在使用调试信息编译代码时才会出现。保持简单,只记录参数值
- 在上面提到的
建议中,您可以将around()
调用封装到procedure()
中,方便地处理和记录任何异常、堆栈跟踪和/或将选中的异常包装到AspectJ的try catch finally
或简单的SoftException
中,然后重新抛出它们。任何适合你的情况RuntimeException
- 方法调用结果只是
的结果,这也是您需要从procedure()
建议返回的结果。您也可以返回其他内容(但它必须具有正确的返回类型),或者完全跳过around()
,如果出于任何原因您希望跳过目标方法的执行procedure()
我刚才所说的一切都写在AspectJ手册或任何其他AspectJ教程中。下次你可能想在问像这样的一般性问题之前阅读其中的一些内容。所以你要问6个不同的问题(要点的数量),希望有人能为你完成全部工作。我懂了。请问您是否阅读过任何文档,是否尝试过在joinpoint或类似网站上通过auto complete提供的任何方法?此外,您是否意识到这样一个事实,即这种“包罗万象”将大大降低您的应用程序的速度,使所有方法的执行成为目标,并在任何地方提取所有可能的详细信息?您是否考虑过缩进来描述调用层次结构,而不是为每个被调用的方法创建堆栈跟踪?对于调用,堆栈缩进就可以了。这我能应付。自从提出这个问题以来,除了如何记录返回值和异常之外,我已经解决了许多问题。另外,如何在不降低应用程序速度的情况下加快方面的速度?基本上,我希望通过应用程序记录函数调用、返回值和异常。是否有方法避免
procedure()
和try catch
,但实现相同的目标try catch
您必须重新刷新,这样将导致修改堆栈跟踪。另外,procedure()
的作用不仅仅是以最小的开销捕获返回值。如果按照设计,您创建了一个只用于调试的缓慢方面,那么为什么您会担心过早优化呢?头脑正常的人不会总是记录生产环境中的每个方法调用。为什么继续()?它只调用目标方法,无论如何都需要这样做。您可以在返回
后使用,而在抛出
建议后使用,但是您必须多次计算要记录的内容。对于您的目的和around()
建议是最有效的方法。如果你认为你知道得更好,请便吧。