为Java应用程序实现日志记录器

4
我正在尝试使用Apache Common Logging和log4j.xml文件作为配置文件来实现记录器。因此,在实际的Java代码中,我将日志写成:我正在使用Apache Common Logging。
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

我正在记录一些信息,例如在 . 我为每个类创建了一个日志实例。

 private static Log    logger  = LogFactory.getLog( MyClass.class );
    private static final String      name   ="SAM";
    logger.info("name= "+name);
  1. So now my question is does implementing logger like this create a performanace issue?

  2. Is it necessary to check log like

    if ( log.isInfoEnabled( ) ) 
     {
      log.info( "Info message" );
      }
    
在Apache通用日志记录中,他们提到需要这样做,而在log4j中他们则提到这是不必要的,这就导致了困惑。
每次我们在文件中写入日志时都需要吗?
-Sam

1
对于大多数应用程序而言,使用 commons-logging 没有意义。commons-logging 主要适用于库和框架,以便您可以在应用程序中包含不同的组件并将它们记录到同一位置。在构建应用程序时,您应该能够选择一个日志记录实现并始终使用它,因此只使用外观模式会增加问题。 - Nathan Hughes
3个回答

2
  1. 是和否,记录日志总是会降低性能,但有些功能比其他功能更昂贵,例如获取调用类/方法名称使用反射并且非常缓慢。但是普通的日志函数并不那么昂贵如果您在调用日志函数时没有昂贵的语句(这将在检查日志级别之前每次评估。在这种情况下,您可以使用.isLevelEnabled检查以防止评估)。此外,将日志记录到控制台需要比将日志记录到文件花费更长的时间。您可以通过谷歌搜索和log4j的FAQ /手册找到更多信息。

  2. 在记录日志之前不需要检查日志级别。这是在日志函数内部完成的。因此,对于每个级别都有不同的方法或通用日志方法中的级别参数。


我明确检查日志级别的唯一情况是当我有许多低严重性语句分组在一起时。例如,如果我连续有10个debug日志,并且我通常将该类设置为error,我可能会将它们包装在检查中。不过我觉得这并没有任何实质性的区别。 - Windle
那么你的意思是说大部分时间我不需要关心检查级别? - Sam
1
是的,不要检查级别。检查级别是冗余的,并会增加您的代码行数,从而降低代码可读性。 - Simulant

2
记录日志时一个潜在的性能问题通常是,如果某个传递到log方法中的内容转换为字符串的成本非常昂贵。这就是为什么有像isInfoEnabled()这样的方法,以便代码可以避免从参数创建消息字符串(否则info()方法内部的检查太晚了,转换已经完成)。如果传递到日志方法中的对象是字符串或者不太复杂,则is*Enabled()方法将不会那么有用。
值得一试的是SLF4J。它不依赖于类加载器技巧(这是commons-logging被人诟病的重要原因之一),并且它有一种不同的创建日志消息的方式,延迟消息字符串的创建时间,以便启用检查可以在日志记录方法内部进行。

如果我试图捕获异常,例如 logger.error("Exception ", exception),我需要检查是否启用了 error level,因为它会将其转换为字符串?那么对于类似 logger.info("name= "+name) 的情况呢?您能否解释一下? - Sam
@Sam:也许吧。但是对于错误,实际上你总是希望看到它们,所以不需要处理日志级别设置为排除错误的情况(如果这样做,你会有其他问题,比如抛出太多异常 ^_^)。检查启用状态更适用于跟踪和调试日志记录的情况,在某些时候你想要看到大量输出,但在生产环境中要排除它。 - Nathan Hughes

1

有更好的方法来完成所有这些。您可以获得非常出色的性能,而无需添加ifDebugEnabled等方法的混乱。请查看Logback(或SLF4J)之类的内容。这里是关于您想要的API类型的绝佳文档。请注意,Log4J和Commons-Logging没有此类API。使用参数化日志记录


很抱歉,由于应用程序中使用了多种不同级别的框架日志记录,我必须使用Commons Logging。 - Sam
1
SLF4J只是其他库的包装器,因此您仍然可以使用SLF4J API,但在幕后使用Commons Logging。如果不可能实现这一点,那么我建议编写自己的日志记录包装器并实现此类API。这绝对是正确的日志记录方式,可以检查是否应该编写日志条目的速度,但没有额外的代码。 - jjathman
我正在使用log4j进行配置,并将常规日志记录作为前端。 - Sam
1
@Sam 看看这个,它描述了这个是如何工作的。增加另一个库可能有些麻烦,但 SLF4J/Logback API 是更好的记录日志方式,所以我认为值得一试。http://www.slf4j.org/legacy.html - jjathman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接