深入了解Log4j2:特点、优势及替代System.out.println的原因

内容:

深入了解Log4j2:特点、优势及替代System.out.println的原因

1.log4j是什么

2.log4j的特点

3.为什么要用Log4j来替代System.out.println

1.log4j是什么

Log4j 是 Apache 的一个开源项目。通过使用Log4j,我们可以控制日志信息传输的目的地到控制台、文件、GUI组件,甚至socket服务器、NT事件记录器、UNIX Syslog守护进程等;我们还可以控制每条日志的输出格​​式;通过定义各个日志信息的级别,我们可以更详细地控制日志的生成过程。

2.log4j的特点

3.为什么要用Log4j来代替System.out.println

关于 log4j 的五个问题和解答:

(1)什么时候使用log4j,什么时候使用System.out.println?

System.out.println可以在开发时使用,日志文件在项目部署后使用。最好不要使用System.out.println。

(2)log4j会影响性能吗?

是的,log4j 会减慢进程响应时间

(3)为什么log4j日志的最高级别是error,但error却是“虽然发生错误事件,但仍然不影响系统的继续运行”?

日志有 7 个级别:

A:off是最高级别,用于关闭所有日志记录。

B:fatal 表示每个严重错误事件都会导致应用程序退出。

C:error 表示虽然发生了错误事件,但仍然不影响系统的继续运行。

D:温暖表示潜在的错误情况。

E:一般性的、粗粒度的信息,强调应用程序的整个运行过程。

F:debug一般用于细粒度级别,对于调试应用程序非常有帮助。

G:所有最低级别,用于开启所有日志记录。

Log4j建议使用四种类型:debug、info、warn、error

(4)log4j文件保存在哪里?

将其存储在项目目录中:

${task5.root}/WEB-INF/logs/log.log

(5)log4j是否打印堆栈信息?

log.info("xxx", e)

转载原文:为什么要用Log4j来代替System.out.println

看到log4j有优点也有缺点,下面我就来看看为什么我们应该将slf4j与log4j结合使用,以及为什么我们应该使用SLF4J而不是Log4J来进行Java日志记录。

每个 Java 开发人员都知道日志记录对于 Java 应用程序(尤其是服务器端应用程序)的重要性,并且他们中的许多人已经熟悉各种日志记录库,例如 java.util.logging、Apache 的 log4j 和 logback ,但是如果您不知道了解 SLF4J,Java 的简单日志记录设计,那么是时候学习它并在您的项目中使用它了。在本 Java 文档中,我们将了解为什么使用 SLF4J 比使用 log4j 或 java.util.logging 更好。自从我为 Java 开发人员撰写 10 个日志记录技巧以来,已经有很长一段时间了。我不记得我写过任何关于日志记录的内容。不管怎样,让我们​​回到主题,与所有这些提到的日志库相比,SLF4J 和它们之间有一个主要区别。 SLF4J 或 Java 的简单日志记录设计实际上并没有实现日志记录,而只是一个抽象层,允许您在后端使用任何日志记录库。如果您正在编写供内部或外部使用的 API 或应用程序库,那么您确实不需要要求使用您编写的库的客户来选择日志记录库。假设该项目已经使用了 log4j,并且您包含了一个名为 Apache Active MQ 的库,该库还依赖于另一个日志记录库 logback,那么您还需要包含它们。但是,如果 Apache Active MQ 使用 SLF4J,您可以继续使用您的日志记录库,而无需添加和维护新的日志记录框架。简而言之,SLF4J 使您的代码独立于任何特定的日志记录 API,这对于公共 API 开发人员来说尤其是一个好主意。虽然日志库的抽象思想并不新鲜,而且Apache的commons日志库也使用了这个概念,但SLF4J很快就会成为Java世界的标准日志库。让我们看看使用 SLF4J 而不是 log4j、logback 或 java.util.logging 的一些原因。

宁愿使用 SLF4J 而不是 Log4J、logback 和 java.util.Logging

正如我之前所说,使用 SLF4J 在代码中编写日志语句的主要动机是使您的程序独立于任何特定的日志库,这可能需要与您现在拥有的配置不同的配置,而且还会引入更多的维护麻烦。不过,除此之外,SLF4J API 还有一个更有说服力的功能,可以让你使用 SLF4J 来代替你感兴趣已久的 Log4j,那就是占位符函数,用 {} 表示在代码中。占位符函数与 String 的 format() 方法中的 %s 非常相似,因为它提取运行时提供的真实字符串。这不仅减少了代码中字符串串联的次数,还减少了创建 String 对象所需的资源。即使生产环境中可能不需要日志级别(例如 DEBUG 和 INFO)的字符串连接,它仍然可以具有相同的效果。由于字符串是不可变的并且它们是在字符串池中创建的,因此这些字符串使用堆内存,并且在应用程序在生产环境中以错误级别运行时在大多数情况下是不必要的。是的,例如DEBUG语句中的字符串不是必需的。通过使用 SLF4J,您可以将字符串的创建推迟到运行时,这意味着仅在需要时才创建字符串。如果您使用过 log4j,那么您已经熟悉将调试语句放在 if() 条件中的工作场景,并且 SLF4J 占位符函数比 log4j 更适合这种场景。

这是使用 Log4j 时所做的事情,当然这并不有趣,而且它增加了不必要的公式化代码并降低了代码的可读性。

if (logger.isDebugEnabled()) {
    logger.debug("Processing trade with id: " + id + " symbol: " + symbol);
}

而如果使用SLF4J,则可以使用更简洁的格式来达到同样的效果,如下:

logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol);

在SLF4J中,我们不需要进行字符串拼接,不会造成临时字符串的消耗。相反,我们使用带有占位符的模板消息来记录信息并提供实际值作为参数。也许您想知道如果有多个参数该怎么办。您可以使用带参数的 log 方法,或通过对象数组传入它。这确实是一种非常方便、高效的记日记方式。请记住,在生成日志消息的最终字符串之前,该方法会检查是否启用了特定的日志级别,这不仅减少了内存使用量,还减少了提前执行字符串连接所消耗的 CPU 时间。下面SLF4J日志方法的代码来自slf4j-log4j12-1.6.1.jar包中的Log4j适配器类Log4jLoggerAdapter。

public void debug(String format, Object arg1, Object arg2) { if (logger.isDebugEnabled()) {
      FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
      logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable());
    }
}

还值得注意的是,日志记录也会对应用程序性能造成压力,并且通常主张仅在生产环境中强制记录日志记录。

如何使用 SLF4J 和 Log4J 进行日志记录

除了上面提到的好处之外,我认为还有一个警告需要说。为了使用SLF4J,不仅需要进入SLF4J API Jar包,如slf4j-api-1.6.1.jar,还需要引入协同JAR包,具体的jar包依赖于日志工具库你在后端使用。如果你想使用SLF4J、Simple Logging Facade for Java和Lo4J,那么你需要将以下jar包引入到你的classpath中。具体版本取决于您使用的SLF4J和log4J版本,例如:

slf4j-api-1.6.1.jar – SLF4J API 的 JAR

log4j-1.2.16.jar – Log4J API 的 JAR

slf4j-log4j12-1.6.1.jar - 适用于 SLF4J 的 Log4J 适配器

如果您使用Maven来管理项目依赖项,则只能导入SLF4J JAR,然后Maven会导入它所依赖的其他JAR包。为了使用 Log4J 和 SLF4J,您可以将以下依赖项添加到项目的 pom.xml 中:


        org.slf4j
        slf4j-log4j12
        1.6.1


        org.slf4j
        slf4j-log4j12
        1.6.1
 

顺便说一句,如果您有兴趣使用参数化版本的日志记录方法,则需要引入 SLF4J 1.7 版本。

总结

总结这篇文章,我有充分的理由选择 SLF4J,而不是直接选择 Log4j、commonslogging、logback 或 java.util.logging。

1)在您的开源库或私有库中使用SLF4J可以使其独立于任何日志记录实现,这意味着无需管理多个库和多个日志文件。您的客户会欣赏这一点。

2) SLF4J 提供占位符日志记录,通过删除对 isDebugEnabled()、isInfoEnabled() 等的检查来提高代码可读性。

3)通过使用logging方式,只有使用时才会构造日志信息(字符串),同时提高了内存和CPU的使用率。

4) 顺便说一句,更少的临时字符串意味着垃圾收集器的工作更少,这意味着应用程序的吞吐量和性能更好。

这些优点只是冰山一角,当您开始使用 SL4J 并阅读相关内容时,您将了解更多内容。我强烈建议 Java 中的任何新代码开发都应使用 SLF4J,而不是任何日志记录 API,包括 log4J。

你可能想看:
« 上一篇
下一篇 »

相关推荐

java中什么是冒泡,冒泡算法

2026年09月06日

27阅读

java中冒号,java双冒号

2026年09月06日

26阅读

java中的->,java中的是什么意思

2026年09月06日

24阅读

java中的super用法,Java中super的说明

2026年09月06日

28阅读

java中反射的应用,java中反射的应用场景

2026年09月06日

25阅读

java中开关的定义,Java关键字有哪些

2026年09月06日

25阅读