Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用EclipseApectJ注入一个日志记录器,记录执行代码的上下文/元数据?_Java_Aop_Aspectj - Fatal编程技术网

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()
    调用封装到
    try catch finally
    中,方便地处理和记录任何异常、堆栈跟踪和/或将选中的异常包装到AspectJ的
    SoftException
    或简单的
    RuntimeException
    中,然后重新抛出它们。任何适合你的情况
  • 方法调用结果只是
    procedure()
    的结果,这也是您需要从
    around()
    建议返回的结果。您也可以返回其他内容(但它必须具有正确的返回类型),或者完全跳过
    procedure()
    ,如果出于任何原因您希望跳过目标方法的执行

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

所以你要问6个不同的问题(要点的数量),希望有人能为你完成全部工作。我懂了。请问您是否阅读过任何文档,是否尝试过在joinpoint或类似网站上通过auto complete提供的任何方法?此外,您是否意识到这样一个事实,即这种“包罗万象”将大大降低您的应用程序的速度,使所有方法的执行成为目标,并在任何地方提取所有可能的详细信息?您是否考虑过缩进来描述调用层次结构,而不是为每个被调用的方法创建堆栈跟踪?对于调用,堆栈缩进就可以了。这我能应付。自从提出这个问题以来,除了如何记录返回值和异常之外,我已经解决了许多问题。另外,如何在不降低应用程序速度的情况下加快方面的速度?基本上,我希望通过应用程序记录函数调用、返回值和异常。是否有方法避免
procedure()
try catch
,但实现相同的目标
try catch
您必须重新刷新,这样将导致修改堆栈跟踪。另外,
procedure()
的作用不仅仅是以最小的开销捕获返回值。如果按照设计,您创建了一个只用于调试的缓慢方面,那么为什么您会担心过早优化呢?头脑正常的人不会总是记录生产环境中的每个方法调用。为什么
继续()?它只调用目标方法,无论如何都需要这样做。您可以在返回
后使用
,而在抛出
建议后使用
,但是您必须多次计算要记录的内容。对于您的目的和
around()
建议是最有效的方法。如果你认为你知道得更好,请便吧。