日志记录是一个关键因素,在软件开发过程中应始终将其考虑在内。
当生产中发生不良情况时,日志文件通常是我们进行故障分析的起点。 而且,通常,它们是我们掌握的唯一信息,可以了解发生了什么以及问题的根本原因。
正确记录所需的信息非常重要。
以下五个日志记录规则是一种检查方法,可能会改善我们处理代码中日志记录的方式。
请注意,我们不会讨论如何配置日志记录引擎,也不会将它们相互比较。
规则1.日志适用于读者
日志消息对谁将读取日志文件有意义,而不仅对谁编写了(日志)代码有意义。
这似乎是很明显的规则,但经常被违反。
例如,让我们考虑类似以下ERROR: Save failure - SQLException .....
的日志消息ERROR: Save failure - SQLException .....
保存什么? 该消息可能对开发人员来说意味着什么,但对于正在考虑生产问题的可怜人来说却完全没有用。
更好的消息是ERROR: Save failure- Entity=Person, Data=[id=123 surname="Mario"] - SQLException....
其中说明了您要保存的内容(这里是一个Person,一个JPA实体)以及Person实例的相关内容。 请注意“ relevant ”一词,而不是“ all all” :我们不应该使日志文件杂乱无章的信息,如所有实体字段的完整打印。 实体名称及其逻辑键通常足以识别表中的记录。
规则2.使日志记录级别与执行环境匹配
Java生态系统中可用的所有日志记录外观和引擎都具有日志记录级别(ERROR,INFO…)的概念,并且有可能过滤掉级别太低的消息。
例如, Java util日志记录使用以下级别:SEVERE,WARN,INFO,FINE,FINER,FINEST(+ CONFIG和OFF)。
相反,两个最受欢迎的日志记录外观Apache Commons Logging和SLFJ首选以下级别:FATAL,ERROR,WARN,INFO,DEBUG,TRACE。
日志记录级别过滤应取决于代码的开发阶段:生产中的日志记录级别不应与测试/集成环境中的日志记录级别相同。
此外,日志记录级别还应该取决于代码所有者 。 通常,与我们使用的任何第三方库相比,我们自己的应用程序代码应具有更详细的日志记录。 例如,在我们的日志文件中查看Apache Commons调试消息没有太大的意义。
我通常将日志记录配置如下:
- 生产 :我的代码为INFO级别,第三方库为WARN。
- 测试/集成 :我的代码的调试级别,以及第三方库的警告(或信息,如果需要)。
- 发展 :任何有意义的
注意:我个人不鼓励使用TRACE / FINEST级别(而且我并不孤单,例如,请参见此处 )。 我看不出DEBUG和TRACE之间有什么大的区别,对于年轻的团队成员来说,通常很难决定要使用DEBUG还是TRACE。 遵循Kiss原则 ,我建议仅使用ERROR,WARN,INFO和DEBUG级别。
规则3.提交前删除编码帮助日志。
在编码时,我们通常使用logger
或System.out
在我们的代码中添加日志消息,以更好地了解执行/调试会话期间应用程序中正在发生的事情。
就像是:
void aMethod(String aParam) {LOGGER.debug(“Enter in aMethod”);if (“no”.equals(aParam)) {LOGGER.debug(“User says no”);….
这些消息的主要目的是通过显示调用哪个方法以及转储内部变量和方法参数值来跟踪应用程序行为。 在非TDD爱好者中颇受欢迎。
不幸的是,一旦代码发布(测试然后生产),这些消息通常没有什么大的意义。
因此,该规则只是说:一旦完成开发,就在将代码提交给使用的SCM系统(git,svn ..)之前,删除所有临时和不必要的日志记录消息。
该规则不需要删除所有DEBUG消息,而仅删除那些在应用程序完成并释放后没有任何意义的消息。 换句话说,当我们合理确定应用程序正常运行时。
规则4:在记录DEBUG消息之前检查日志级别
根据规则2,在生产日志中,我们将仅显示ERROR,WARN,INFO消息,但是在我们的代码中,我们可以具有许多不影响生产执行的DEBUG消息。
每次您要记录DEBUG消息(规则3之后的所有消息)时,请在前面添加检查是否启用了DEBUG记录:
if ( LOGGER.isDebugEnabled() ) {LOGGER.debug (…….)}
这将防止您编写代码来构建日志消息并调用记录器。 这是为了提高生产中程序的执行效率。
规则5:了解您的记录器
我们如何使用记录器方法会产生巨大的成本:
- 构建消息字符串
- 收集要包含在消息字符串中的数据
我们应该查看所选日志外观/引擎的Javadoc ,并了解使用其记录器的最有效方法。
例如,我们可以创建如下消息:
LOGGER.info(“Person name is “ + person.getName());
这会创建不必要的字符串实例。
使用SLF4J,正确的用法是:
LOGGER.info(“Person name is {}“, person.getName());
其中格式字符串是常量,并且仅在启用日志记录后才生成最终消息。 有关更多详细信息,请参见此处 。
翻译自: https://www.javacodegeeks.com/2015/12/5-java-logging-rules.html