Log4j2与Logback对比:为什么Log4j2成为JAVA日志框架的新王者

2025-03-13
来源:网络整理

这是Java中的一个旧日志框架。它是自2006年以来的第一个版本,已经迭代了十多年。但是,最新的稳定版本仍在2017年,几年没有更新。兄弟的最新稳定版本也在2017年,这有点酷。

此外,异步性能确实是扩展的,功能很简单,配置很麻烦,新一代的记录框架远远不如 -

目前,它是国王,其他日志框架与他们不匹配!

介绍

2是(1)的升级版本,它已经从其祖先1。x方面得到了极大的改进,并且从比较中得到了极大的改善。除了调整内部设计外,主要还有以下几点重大升级:

在2中,它分为两个模块:API(-api)和实现(-CORE)。 API,是属于对数抽象/立面的一种类型,实现部分是2的核心。

最强大的异步性能

从图可以看出,异步(完整异步,非混合模式)中的性能远远超过了总和,这只是一个很大的打击。压力越大,吞吐量中的间隙越大。

在64个线程测试下,吞吐量达到180W+ / s, / / / / / s小于20W,几乎是差异的十倍

零gc( - free)较高的性能I/O写作支持

NDER,I/O零件也用于实现极高的I/O性能。

但是,在使用NDER之前,您必须确保自己有足够的知识,否则不要轻易使用它。

更强大的参数格式化

与API模块相比,它提供了更丰富的参数格式化函数。

使用{}占位符的格式参数

这样,我们可以以{}的形式实现“”的功能(参数将直接替换占位符),如下:

logger.debug("Logging in user {} with birthday {}", user.getName(), user.getBirthdayCalendar());

使用形式的格式参数。

除了支持{}的参数占位符外,

public static Logger logger = LogManager.getFormatterLogger("Foo");
 
logger.debug("Logging in user %s with birthday %s", user.getName(), user.getBirthdayCalendar());
logger.debug("Logging in user %1$s with birthday %2$tm %2$te,%2$tY", user.getName(), user.getBirthdayCalendar());
logger.debug("Integer.MAX_VALUE = %,d", Integer.MAX_VALUE);
logger.debug("Long.MAX_VALUE = %,d", Long.MAX_VALUE);

,需要使用。不是。

使用.参数

接口中还有另一种可以以形式使用的方法。

logger.printf(Level.INFO, "Logging in user %1$s with birthday %2$tm %2$te,%2$tY", user.getName(), user.getBirthdayCalendar());

logger.debug("Opening connection to {}...", someDataSource);

“懒惰”记录(懒惰)

微信程序日志是什么_日志输出什么意思_微信小程序开发控制台日志输出

尽管此功能很小,但非常实用。

在某些业务流程中,为了保留根本或跟踪问题,需要完全打印参数。通常,参数与JSON/XML序列化,然后以级别打印:

logger.debug("入参报文:{}",JSON.toJSONString(policyDTO));

如果您需要跟踪问题,则系统的日志级别将被调整为 /,以便可以打印它。但是这里有一个问题。尽管内容不会在信息级别输出,但是JSON的序列化代码肯定会执行,这会严重影响正常流程下的执行效率。

我们期望的结果是,在信息级别上,甚至没有执行序列化。在这里,我们可以确定当前配置级别是否可以输出:

if(logger.isDebugEnabled()){
    logger.debug("入参报文:{}",JSON.toJSONString(policyDTO));
}

尽管这可以避免不必要的序列化,但是在每个地方都这样写它仍然有些不舒服,一条线变成三行。

 JSON.toJSONString(policyDTO));if(logger.isDebugEnabled()){    logger.debug("入参报文:{}",JSON.toJSONString(policyDTO));}这种 Supplier + Lambda 的形式,等同于上面的先判断 isDebugEnable 然后打印,三行的代码变成了一行。" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;">void debug(String message, Supplier... paramSuppliers);
void info(String message, Supplier... paramSuppliers);
void trace(String message, Supplier... paramSuppliers);
void error(String message, Supplier... paramSuppliers);

//等同于下面的先判断,后打印
logger.debug("入参报文:{}",() -> JSON.toJSONString(policyDTO));

if(logger.isDebugEnabled()){
    logger.debug("入参报文:{}",JSON.toJSONString(policyDTO));
}

好吧,闻起来很好。

更简化的配置

2它还支持四种形式的配置文件:XML/JSON/YML/,但最主流的是XML方法,它是最直观的。 ,建议看看。

让我们看一下配置文件的比较和相同函数的配置:

.xml


<configuration>
 <appender name = "File" class"ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/app.logfile>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>logs/archives/app-%d{yyyy-MM-dd}.log.gzfileNamePattern>
   
           <maxFileSize>1 GBmaxFileSize>
        rollingPolicy>
    appender>
    <root level="info">
      <appender-ref ref="File"/>
    root>
configuration>

.xml

                                                                                                                                                                " data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;">
<Configuration xmlns:xi="http://www.w3.org/2001/XInclude"
               status="warn" name="XInclude">

    <Appenders>
          <RollingFile name="File" fileName="logs/app.log" filePattern="logs/archives/app-%d{yyyy-MM-dd}-%i.log.gz">
              <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p [%t] %-40.40c{1.} : %m%n"/>
              <Policies>
                  <TimeBasedTriggeringPolicy />
                  
                  <SizeBasedTriggeringPolicy size="1 GB"/>
              Policies>
          RollingFile>
    Appenders>
    <Loggers>
        <Root level="INFO">
            <AppenderRef ref="File"/>
        Root>
    Loggers>
Configuration>

在此,从使用实现名称的使用中,配置更简单,即标签名称:

<RollingFile name="File">


<appender name = "File" class"ch.qos.logback.core.rolling.RollingFileAppender">

适应其他日志抽象/外墙

由于它分为两个部分:API和实现,因此也可能需要适应其他日志框架。有关详细的日志框架改编解决方案,请参阅我的文章中的另一篇文章。

其他功能

异步队列使用高性能队列-LMAX

丰富,并获得各种支持,例如JMS/JPA // http ////

支持自定义日志级别

...

基本用法

日志输出什么意思_微信程序日志是什么_微信小程序开发控制台日志输出

最后,我介绍了游戏的力量。现在,让我们介绍基本用法。

参考的依赖

-API已经在-core中具有依赖性,只需直接依靠核心

<dependency>
    <groupId>org.apache.logging.log4jgroupId>
    <artifactId>log4j-coreartifactId>
    <version>2.14.1version>
dependency>

请注意,当引用时,您需要注意项目中是否存在多组日志框架和适应性问题。有关详细信息,请参阅上面的详细信息:请参阅上面的适应其他日志抽象/立面。

配置文件示例

首先,配置文件,默认配置文件路径为::。xml(建议使用XML)

                                                                                                                                                                                                                                                                                                                   " data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;">
<Configuration xmlns:xi="http://www.w3.org/2001/XInclude"
               status="warn" name="XInclude">

    <Properties>
      <Property name="PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p [%t] %-40.40c{1.} : %m%n"/>
    Properties>
    <Appenders>
        
          <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="${PATTERN}"/>
          Console>
       
        
          <RollingFile name="File" fileName="logs/app.log" filePattern="logs/archives/app-%d{yyyy-MM-dd}-%i.log.gz">
              <PatternLayout pattern="${PATTERN}"/>
              <Policies>
                 
                  <TimeBasedTriggeringPolicy />
                  
                  <SizeBasedTriggeringPolicy size="1 GB"/>
              Policies>
          RollingFile>
    Appenders>
    <Loggers>
       
       
       <Logger name="your logger/package name" level="debug" additivity="false"/>
       
        <Root level="INFO">
           
           
            <AppenderRef ref="Console"/>
           <AppenderRef ref="File"/>
        Root>
    Loggers>
Configuration>

XML配置文件语法

;
<Configuration>
  <Properties>
    <Property name="name1">valueproperty>
    <Property name="name2" value="value2"/>
  Properties>
  <filter  ... />
  <Appenders>
    <appender ... >
      <filter  ... />
    appender>
    ...
  Appenders>
  <Loggers>
    <Logger name="name1">
      <filter  ... />
    Logger>
    ...
    <Root level="level">
      <AppenderRef ref="name"/>
    Root>
  Loggers>
Configuration>

创造

直接使用API​​:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

Logger logger = LogManager.getLogger(Log4j2Test.class);
logger.error(...);
logger.warn(...);
logger.info(...);
logger.debug(...);
logger.trace(...);

如果结合使用,也可以。只需遵循之前提到的内容,提前进行改编,然后使用API​​。但是,如果是一个新系统,建议直接使用API​​,以便您可以享受所有功能。使用此类API时,无法使用上述功能,例如参数格式。

完全异步配置(重要!!)

建议将完全异步配置(全部)配置,并在启动脚本中添加系统变量配置:

-Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

总结

现在,它具有最强的性能,最强的功能,并不断地更新和维护。

你还在等什么?是时候取代您了!

为了解决话题,伯德兄弟是一个喜欢四处乱逛的程序员。他喜欢开发自己的网站,迷你程序,应用程序等。所有这些都与服务器密不可分!最近,我围绕服务器的主题创建了一个微信小组。喜欢与服务器一起玩或想自己开发产品的读者可以互相学习!在小组通知中,我在构建服务器上共享了一组视频教程。非常适合初学者学习!我还会带您不时获得与服务器相关的优惠券!如果您不感兴趣并且不喜欢遇到麻烦,则无需加入!

识别QR码并添加微信

发送[服务器]获取邀请链接

分享