Java日志记录的5条规则

日志记录是在软件开发过程中常常需要考虑的关键因素。

当产品运行出错时,日志文件通常是我们进行错误分析的首要选择。

而且,在很多情况下,它们是我们手上唯一可以用来查明发生状况和问题根本原因的信息。

可见,正确记录需要的信息是极其重要的。

以下5条日志规则,让我们可以检查和改进在代码中操作日志记录的方式。

同时也请注意,我们既不会讨论怎么配置一个日志引擎,也不会相互比较。

规则1、日志是面向读者的

日志消息不仅要对书写(日志)代码的人有意义,也应该对日志文件的读者有意义。

这似乎是一条很明显但却经常违背的规则。


1

ERROR:
Save failure - SQLException .....

举个例子吧,我们来看看下面这条日志信息:


1

ERROR:
Save failure - SQLException .....

保存什么呢?这条消息在开发者看来是能说明一些问题的,但是对于正在苦苦查看产品问题的可怜家伙来说,却毫无用处。


1

RROR:
Save failure- Entity=Person, Data=[id=
123

surname=
"Mario"]
- SQLException....

更合适的信息是这样的:


1

RROR:
Save failure- Entity=Person, Data=[id=
123

surname=
"Mario"]
- SQLException....

这就解释了你想要存储的东西(这里是一个 Person,是一个 JPA 实体)以及这个 Person 实例相关的内容。

请注意相关这个单词,并不是指泛泛的全体:我们不应该让无价值的信息使日志文件变得乱糟糟,比如说完整打印所有的实体字段。

通常,实体名字和其逻辑关键字足以识别在表格中的一条记录了。

规则2、匹配日志等级和执行环境

在 Java 系统中提供的所有日志管理工具和引擎都有日志等级(ERROR、INFO……)的概念,这将有可能过滤掉等级过低的消息。

例如,Java util logging 使用如下的等级:SEVERE、WARN、INFO、FINE、FINER、FINEST(+
CONFIG 和 OFF)。相反,两个最受欢迎的日志管理工具, Apache
Commons Logging
 和 SLFJ更倾向于如下的等级:FATAL、ERROR、WARN、INFO、DEBUG、TRACE。

日志过滤等级则需要取决于代码的开发阶段:成品与仍处在测试、集成环境下的代码日志等级就不能相同。

更具体的来说,日志等级也应该参考代码的归属情况。

一般而言,我们自己的应用程序代码应该比使用的任何第三方开发库拥有更详细的日志记录。

比如说,Apache 的通用调试消息出现在我们的日志文件中,就没有多大意义。

我通常像这样配置日志记录:

  • 成品阶段: 我的代码是 INFO 等级,第三方库是 WARN。
  • 测试、集成阶段:我的代码是 DEBUG 等级,第三方库是 WARN(或者如果需要的话是 INFO)。
  • 开发阶段:任何有意义的信息。

注意:个人而言,我不建议使用 TRACE/FINEST 等级(我并不是唯一持这种观点的人,可以参考 这里 的例子)。

我并没有发现 DEBUG 和 TRACE 有多大的区别,而年轻团队的成员常常苦恼于到底是使用 DEBUG 还是 TRACE 。

根据 KISS 原则,我建议只使用 RROR、WARN、INFO 和 DEBUG 等级。

规则3、提交前去除编码帮助日志

编码时,我们常常会使用 logger 或是 System.out 在代码中添加日志消息,来更好地掌握应用程序在执行、调试期间发生的状况。


1

2

3

4

5

void

aMethod(String aParam) {

  LOGGER.debug(“Enter
in aMethod”);

  if

(“no”.equals(aParam)) {

  LOGGER.debug(“User
says no”);

  ….

比如这样的代码:


1

2

3

4

5

void

aMethod(String aParam) {

  LOGGER.debug(“Enter
in aMethod”);

  if

(“no”.equals(aParam)) {

  LOGGER.debug(“User
says no”);

  ….

这些消息显示被调用的方法并且备份内部变量及方法参数值,主要是为了追踪应用程序的行为。这在非测试驱动开发中相当受欢迎。

但糟糕的是,一旦代码发布(测试之后成为成品)这些消息通常就无用武之地了。

所以,这条规则简单来说就是:一旦你已经完成开发工作,在将代码提交到使用中的 SCM 系统(git、svn……)之前,要去除所有临时的和不必要的日志消息。

这条规则并不是要求去除所有的 DEBUG 消息,只是针对那些在应用程序完成和发布后就没有意义的消息,或者是说当我们有理由相信应用程序能正确运行时就失去意义的那些消息。

规则4、log DEBUG消息之前检查日志等级

根据第2条规则,在产品日志中,我们只会显示 ERROR、WARN、INFO 等级的消息,但是在代码中我们也可以使用一些不会影响产品运行的 DEBUG 消息。


1

2

3

if

( LOGGER.isDebugEnabled((){

 LOGGER.debug
(…….)

 }

每次你想要 log 一个 DEBUG 消息时(在使用了规则3后的留下的所有消息),需要在前面添加一个检查来明确是否启用了 DEBUG 日志:


1

2

3

if

( LOGGER.isDebugEnabled((){

 LOGGER.debug
(…….)

 }

这种做法可以阻止代码去创建日志消息和调用 logger,提高产品运行程序的效率。

规则5、了解你的 logger

我们使用 logger 方法的方式可能会带来巨大的开销:

  • 创建消息字符串
  • 组织包含在消息字符串中的数据

我们应该查阅所选择的日志管理工具、引擎的 javadoc 文档,了解使用它们 logger 的最有效的方法。


1

LOGGER.info(“Person
name is “ + person.getName());

例如,我们可以创建一条这样的消息:


1

LOGGER.info(“Person
name is “ + person.getName());

这就创建了不必要的字符串实例。


1

LOGGER.info(“Person
name is {}“, person.getName());

使用SLF4J,正确的用法应该是:


1

LOGGER.info(“Person
name is {}“, person.getName());

这里的格式化字符串是常量,不可变消息只有在允许 logging 的情况下才会被创建。

看 这里 可以获得更多细节内容。

原文链接: javacodegeeks 翻译: ImportNew.comJyy

时间: 2025-01-12 13:06:18

Java日志记录的5条规则的相关文章

Java日志记录的事儿

一.java日志组件 1.common-logging common-logging是apache提供的一个通用的日志接口.用户可以自由选择第三方的日志组件作为具体实现,像log4j,或者jdk自带的logging, common-logging会通过动态查找的机制,在程序运行时自动找出真正使用的日志库.但由于它使用了ClassLoader寻找和载入底层的日 志库, 导致了象OSGI这样的框架无法正常工作,由于其不同的插件使用自己的ClassLoader. OSGI的这种机制保证了插件互相独立,

Java日志记录工具SLF4J介绍

SLF4J是什么 SLF4J是一个包装类,典型的facade模式的工具,对用户呈现统一的操作方式,兼容各种主流的日志记录框架,典型的有log4j/jdk logging/nop/simple/jakarta commons logging等. 有张图比较形象直观的展示这个知识: 下面给出几个maven配置的例子 logback-classic <dependency>   <groupId>ch.qos.logback</groupId>  <artifactId

java日志记录之Logger.getLogger()和LogFactory.getLog()的区别

最近研究项目代码时发现同一个项目用到关于日志的两种不同写法: Logger.getLogger()和LogFactory.getLog()的区别 1.Logger.getLogger()是使用log4j的方式记录日志:API文档 2.LogFactory.getLog()则来自apache的common-logging包.API文档 根据不同的性质,日志信息通常被分成不同的级别,从低到高依次是:"调试( DEBUG )""信息( INFO )""警告( W

NLog日志记录

配置NLog NLog支持 .Net 4.5 以及以上版本! 首先去下载NLog的DLL下载地址:http://nlog-project.org/download/  然后把下载下来的Nlog.dll ,Nlog,extension.dll 加入项目reference. 之后就是配置NLog.config  格式如下: 通过在启动的时候对一些常用目录的扫描,NLog会尝试使用找到的配置信息进行自动的自我配置. 在ASP.NET项目中搜索的目录包括: 标准的web程序配置文件web.config

Java 日志框架终极教程

概述 对于现代的 Java 应用程序来说,只要被部署到真实的生产环境,其日志的重要性就是不言而喻的,很难想象没有任何日志记录功能的应用程序被运行于生产环境中.日志 API 所能提供的功能是多种多样的,包括记录程序运行时产生的错误信息.状态信息.调试信息和执行时间信息等.在生产环境中,日志是查找问题来源的重要依据,应用程序运行时的产生的各种重要信息,都应该通过日志 API 来进行记录. 很多Java开发人员习惯于使用 System.out.println.System.err.println 以及

工作经验:Java 系统记录调用日志,并且记录错误堆栈

前言:现在有一个系统,主要是为了给其他系统提供数据查询接口的,这个系统上线不会轻易更新,更不会跟随业务系统的更新而更新(这也是有一个数据查询接口系统的原因,解耦).这时,这个系统就需要有一定的方便的线上查错方式,我便想到了记录每一次的调用日志,而且需要记录错误堆栈,同时被白名单过滤的也要记录下来. 想法 这个日志记录,需要在每一次访问接口时记录一下,在有异常时将异常的堆栈信息记录在每次访问记录里.这里由于要使用数据库信息,所以选择了 spring 的拦截器. 在拦截器抛放心之后,运行业务代码,如

Java学习-007-Log4J 日志记录配置文件详解及实例源代码

此文主要讲述在初学 Java 时,常用的 Log4J 日志记录配置文件详解及实例源代码整理.希望能对初学 Java 编程的亲们有所帮助.若有不足之处,敬请大神指正,不胜感激!源代码测试通过日期为:2015-1-30 13:54:02,请知悉. 所需的 jar 包下载链接为:http://yunpan.cn/cKE56sxqtQCfP  访问密码 63d8 有关 Log4J 日志文件中日志级别及文件配置的详细情况,在 Log4J 的配置文件(xml.properties)中有详细的介绍,敬请参阅!

日志记录的作用和方法 java

程序中记录日志一般有两个目的:Troubleshooting和显示程序运行状态.好的日志记录方式可以提供我们足够多定位问题的依据.日志记录大家都会认为简单,但如何通过日志可以高效定位问题并不是简单的事情.这里列举下面三个方面的内容,辅以代码示例,总结如何写好日志,希望对他人有所启发和帮助: 怎样记日志可以方便Troubleshooting 程序运行状态可以记哪些 应该避免怎样的日志方式 怎样记日志可以方便Troubleshooting? 1. 对外部的调用封装 程序中对外部系统与模块的依赖调用前

JAVA实现通用日志记录

原文:http://blog.csdn.net/jinzhencs/article/details/51882751 前言: 之前想在filter层直接过滤httpServerletRequest请求进行日志处理,但是之后再getWriter()的 时候报 already been call异常.查了下,才发现原来流形式的只能读取一次..就好像食物,吃了就没了.. 所以在filter和inteceptor里面是没法通过获取request的流来进行日志记录的. 于是还是准备用通用的方法:contr