mah*_*ler 11 java logging trace annotations aspects
我一直在使用一个公司的代码库,该公司的策略是编写大量的跟踪日志记录.因此,几乎每个方法都有一段代码,如下所示:
String LOG_METHOD = "nameOfMethod(String,List<Long>):void";
if(logger.isTraceEnabled()) {
Object[] params = new Object[] { string, list };
logger.trace(CompanyMessages.newMethodInstanceMessage(this, LOG_METHOD, params));
}
Run Code Online (Sandbox Code Playgroud)
并以此结束(在finally-clause中或在方法的最后:
if(logger.isTraceEnabled()) {
logger.trace(CompanyMessages.leaveMethodInstanceMessage(this, LOG_METHOD));
}
Run Code Online (Sandbox Code Playgroud)
实际上有更多的代码,但这是基本的想法.这使得代码变得混乱,其他编码人员不断地使用他们自己的解释来搞乱它,这些解释不使用CompanyMessages格式化监视工具要读取的消息所需的特定类.所以我正在寻找一种方法来摆脱上面的所有代码,并提供所有需要跟踪记录的方法,注释如下:@LogBefore('logLevel')&@LogAfter('logLevel').
我选择这个解决方案的原因是为了使其他开发人员不必学习任何新东西,而是使用注释而不是代码.我在一个服务器环境中工作,我们部署了数百个Web应用程序和数十个开发人员.所以我一直在寻找一种在Web应用程序中实现它的方法,而无需额外的编码或额外的大型库.这意味着我正在寻找一个小的,稳定的AOP实现,使用类似于我提出的注释,在每个Web应用程序中易于配置.表现也很重要.用AOP实现这个的最简单的例子是什么?
编辑:我确实找到了与我正在寻找的非常类似的东西,但这有几个问题.必须配置所有需要日志记录的类,这比仅使用注释更耗费资源.弹簧配置会<aop:aspectj-autoproxy/>修复吗?
注释和AOP点都是有效的.使用注释来警告AOP框架有关日志记录的信息.
我要做的另一件事是修复你的记录器.
你有:
String LOG_METHOD = "nameOfMethod(String,List<Long>):void"
if(logger.isTraceEnabled()) {
Object[] params = new Object[] { string, list };
logger.trace(CompanyMessages.newMethodInstanceMessage(this, LOG_METHOD, params) );
}
Run Code Online (Sandbox Code Playgroud)
相反,考虑这样的事情:
logger.trace(this, LOG_METHOD, string, list);
Run Code Online (Sandbox Code Playgroud)
你可以像这样实现它:
public void trace(Object obj, Object args...) {
if (parentLogger.isTraceEnabled()) {
logger.trace(CompanyMessages.newMethodInstanceMessage(obj, LOG_METHOD, args);
}
}
Run Code Online (Sandbox Code Playgroud)
大多数日志实用程序都是在我们用Java编写varargs之前编写的,所以我们仍然会看到类似你编写的内容.
我们还希望防护能够防止在未启用时调用日志,但主要动机是因为过去大多数人会做你做过的事情,或者更糟糕的是:
logger.trace("My message: " + string + " with list " + list);
Run Code Online (Sandbox Code Playgroud)
无论是否启用跟踪,都有一个昂贵的表达式.
但是通过利用varargs,你可以获得两者.只需使用MessageFormat之类的东西(您可能已经在做),您可以轻松获得:
logger.trace("My message: {0} with list {1}", string, list);
Run Code Online (Sandbox Code Playgroud)
禁用跟踪,这是一个通过3个指针的廉价方法调用.因此,保护它并使代码混乱的动机要少得多.
大多数现代记录器都没有很好地覆盖,因此您通常必须封装它而不是简单地扩展它.
它不直接解决您的问题,动态生成跟踪信息.但这是一个简单的中间立场,可以轻松地,逐步地清理现有的代码库.
此外,还有其他2个选项.
一个是使用运行代码的后处理器,并将登录添加到尚不存在的位置.这样可以节省您手动输入的负担,但它会使代码混乱(因为它仍然存在于任何地方).
二,是在编译时使用注释处理器.这更复杂.但它的作用是在编译期间,它在编译时通过信息运行并扩充您的类.好的是你的代码是干净的(除了注释之外),但是所有的工作都是在编译时完成的.没有运行时影响而不是Object工厂的花哨类加载器.一旦构建完毕,您就可以将处理器丢弃,在运行时根本不需要它.
有一个项目,谁的名字逃脱了我,利用这一点.它会在编译时自动将setter/getter添加到您的代码中.我听说过这件好事.
AOP框架很可能在编译时为你做这个,我对他们不太熟悉,但不管怎样,这种技术值得探索.
但至少要包装你的记录器.它是增量的,安全的,并且会逐渐清理代码并帮助您进行日志记录,而注释可能对您不起作用.