使用Eclipse AspectJ注入记录执行代码的上下文/元数据的记录器?

问题描述

我正在尝试定义一个方面来注入记录器。

我正在寻找类似的东西

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("{}.{} = {}",result);
    }
}

为此,我要检索执行元数据/上下文数据:

  • 例外
  • 返回值

如何获取此元数据/上下文数据?

解决方法

为了保持您的方面高效,我建议以下内容:

  • 将切入点限制为您真正希望调试的目标包和类。不要记录/追踪整个世界。您还可以将抽象基础方面与抽象切入点一起使用,并将方面扩展为具有具体切入点的具体子方面。如果您使用加载时间编织,甚至可以通过XML配置提供后者。
  • 使用around()建议而不是before() / after()对。然后,您只需要计算一些记录的值,并在通过proceed()完成原始方法调用之前和之后使用它们。
  • 仅记录thisJoinPoint而不是默认情况下将其中包含的位拼凑在一起。这将为您提供连接点的类型,方法签名(包括参数类型和返回值)。
  • 不记录参数名称,该信息不增加任何实际值。此外,参数名称可以进行重构,并且仅当您的代码是使用调试信息编译的时候才存在。保持简单,只记录参数值。
  • 在上述around()建议中,您可以将proceed()调用包含到try-catch-finally中,并方便地处理和记录任何异常和堆栈跟踪,和/或将检查的异常包装到AspectJ的{{1 }}或简单的SoftException并重新抛出它们。无论哪种情况都适合您。
  • 方法调用结果只是RuntimeException的结果,这也是您从proceed()建议中返回的结果。如果出于某种原因希望跳过目标方法的执行,也可以返回其他内容(但必须具有正确的返回类型)或完全跳过around()

我刚才说的所有内容都写在AspectJ手册或任何其他AspectJ教程中。您可能想在下次问像这样的一般问题之前阅读其中的一些内容。