日志框架Logback和Log4j2该如何选择?

924331c4ce0998126cca6cf998290b9f.png

1、Logback

1.1、Logback简介

Logback是由log4j创始人设计的又一个开源日志组件。

Logback当前分成三个模块:logback-core,logback- classic和logback-access

  1. logback-core是其它两个模块的基础模块,类似与springframework

  2. logback-classic是log4j的一个改良版本。此外logback-classic完整实现SLF4J API。使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging

  3. logback-access访问模块与Servlet容器集成提供通过Http来访问日志的功能

1.2、Logback中的组件

  1. Logger:日志的记录器,主要用于存放日志对象,也可以定义日志类型、级别

  2. Appender:用于指定日志输出的目的地,目的地可以是控制台、文件、数据库等等

  3. Layout:负责把事件转换成字符串,格式化的日志信息的输出。在Logback中Layout对象被封装在encoder中。也就是说我们未来使用的encoder其实就是Layout

1.3、基础日志输出格式

%-10level 级别:案例为设置10个字符,左对齐
%d{yyyy-MM-dd HH:mm:ss.SSS}:日期
%c:当前类全限定名
%M:当前执行日志的方法
%L:行号
%thread:线程名称
%m或者%msg:信息
%n:换行

1.4、基础配置文件格式

<?xml version="1.0" encoding="UTF-8"?>


   <!--scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
       scanPeriod: 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
    debug: 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。-->
   <configuration scan="true" scanPeriod="60 seconds">
 


    <!--定义变量 ,可被插入到logger上下文中,此处定义日志文件的存储地址-->
    <property name="log.base.run" value="../logs/sshblog"/>




       <!--JMX管理,logback支持使用JMX随时重载logback.xml或者单独设置某个package的levelscan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。-->
    <jmxConfigurator/>


    <!--输出到控制台-->
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <!--日志格式化-->
        <encoder>
            <pattern>[sshblog]|%-20(%date|[%thread])|%-1level|%logger{80}| %msg%n</pattern>
        </encoder>
        <!--字符串System.out(默认)或者System.err-->
        <target>System.out</target>
    </appender>
    <!--滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件-->
    <appender name="logfileRun" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- <Encoding>UTF-8</Encoding> -->
        <!--被写入的文件名-->
        <File>${log.base.run}.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">    <!--当发生滚动时,决定RollingFileAppender的行为,涉及文件移动和重命名。属性class定义具体的滚动策略类,此处class为最常用的,其他的自己去看-->
            <FileNamePattern>${log.base.run}_%d{yyyyMMdd}-%i.log.zip
            </FileNamePattern>    <!--必要节点,可以为活动文件和归档文件指定不同位置,当前日志总是记录到file指定的文件(活动文件),活动文件的名字不会改变-->
            <MaxHistory>15</MaxHistory><!--可选节点,可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。-->
            <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><!--查看当前活动文件的大小,如果超过指定大小会告知RollingFileAppender 触发当前活动文件滚动-->
                <MaxFileSize>50MB</MaxFileSize>
            </TimeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
            <pattern>[sshblog]|%-20(%date|[%thread])|%-1level| %msg [%file:%line]%n
            </pattern>
        </encoder>
    </appender>




    <logger name="com.test" level="trace" additivity="true"><!--用来设置某一个包或具体的某一个类的日志打印级别、以及指定appender。loger仅有一个name属性,一个可选的level和一个可选的addtivity属性。
                                                            name: 用来指定受此loger约束的某一个包或者具体的某一个类。
                                                            level: 用来设置打印级别,大小写无关。
                                                            addtivity: 是否向上级loger传递打印信息。默认是true。经测试,如果此处配置为true,且同一个appender同时添加在此和root,则会打印两次,如果根元素没有配置,则无论配置为true还是false,都只打印一次
                                                            -->
        <appender-ref ref="stdout"/> <!--可以包含零个或多个appender-ref元素,标识这个appender将会添加到这个logger-->
    </logger>




    <logger name="com.xrom.ssh" level="error" additivity="true">
        <appender-ref ref="stdout"/>
    </logger>




    <root level="trace"><!--它也是loger元素,但是它是根loger,是所有loger的上级。只有一个level属性,因为name已经被命名为"root",且已经是最上级了。
            level: 用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL和OFF,不能设置为INHERITED或者同义词NULL。默认是DEBUG。-->
        <appender-ref ref="logfileRun"/>
        <!--<appender-ref ref="stdout" />-->
    </root>


</configuration>

7c6fa3b609c67fd1153272262379f9b1.png

2、Log4j2

2.1、Log4j2简介

Apache Log4j 2是对Log4j的升级,它比其前身Log4j 1.x提供了重大改进,并提供了Logback中可用的许多改进,同时修复了Logback架构中的一些问题

被誉为是目前最优秀的Java日志框架

2.2、Log4j2特征

性能提升

Log4j2包含基于LMAX Disruptor库的下一代异步记录器

在多线程场景中,异步记录器的吞吐量比Log4j 1.x和Logback高18倍,延迟低

自动重新加载配置

与Logback一样,Log4j2可以在修改时自动重新加载其配置

与Logback不同,它会在重新配置发生时不会丢失日志事件

高级过滤

与Logback一样,Log4j2支持基于Log事件中的上下文数据,标记,正则表达式和其他组件进行过滤

过滤器还可以与记录器关联。与Logback不同,Log4j2可以在任何这些情况下使用通用的Filter类

无垃圾机制

在稳态日志记录期间,Log4j2 在独立应用程序中是无垃圾的

在Web应用程序中是低垃圾。

基本用法

现在来介绍下 Log4j2 的基本使用。

1. 引用 Log4j2 的 Maven 依赖

log4j-api 在 log4j-core 中已经有依赖了,直接依赖 core 即可:

< dependency>
< groupId> org.apache.logging.log4j </ groupId>
< artifactId> log4j-core </ artifactId>
< version> 2.14.1 </ version>
</ dependency>

注意,引用 Log4j2 时,需要注意项目中是否有多套日志框架共存/冲突,需要适配的问题。细节请参考上面的与其他日志抽象/门面适配。

2. 配置文件示例

首先是配置文件,默认的配置文件路径为:classpath:log4j2.xml(推荐使用 xml):

<?xml version="1.0" encoding="UTF-8"?>
< Configurationxmlns:xi= "http://www.w3.org/2001/XInclude"
status= "warn"name= "XInclude">
< Properties>
< Propertyname= "PATTERN"value= "%d{yyyy-MM-dd HH:mm:ss.SSS} %5p [%t] %-40.40c{1.} : %m%n"/>
</ Properties>
< Appenders>
<!-- 输出到控制台,仅在本地开发环境使用 -->
< Consolename= "Console"target= "SYSTEM_OUT">
< PatternLayoutpattern= "${PATTERN}"/>
</ Console>
<!--输出到日志文件,滚动分割日志文件,自动打包gz-->
< RollingFilename= "File"fileName= "logs/app.log"filePattern= "logs/archives/app-%d{yyyy-MM-dd}-%i.log.gz">
< PatternLayoutpattern= "${PATTERN}"/>
< Policies>
<!--默认一天一个文件-->
< TimeBasedTriggeringPolicy/>
<!--一天内大于size就单独分隔-->
< SizeBasedTriggeringPolicysize= "1 GB"/>
</ Policies>
</ RollingFile>
</ Appenders>
< Loggers>
<!-- 添加你的自定义logger,一般用于区分包名的日志,不同包名不同的级别/appender -->
<!-- additivity 意思是,调用完当前appender,是否继续调用parent logger appender,默认true-->
< Loggername= "your logger/package name"level= "debug"additivity= "false"/>
<!--默认的Root Logger 级别-->
< Rootlevel= "INFO">
<!--这里需要区分下环境(配合maven profile之类的)-->
<!-- 开发环境使用Console Appender,生产环境使用File Appender -->
< AppenderRefref= "Console"/>
< AppenderRefref= "File"/>
</ Root>
</ Loggers>
</ Configuration>

3. XML 配置文件语法

<?xml version="1.0" encoding="UTF-8"?>;
< Configuration>
< Properties>
< Propertyname= "name1"> value </ property>
< Propertyname= "name2"value= "value2"/>
</ Properties>
< filter.../>
< Appenders>
< appender...>
< filter.../>
</ appender>
...
</ Appenders>
< Loggers>
< Loggername= "name1">
< filter.../>
</ Logger>
...
< Rootlevel= "level">
< AppenderRefref= "name"/>
</ Root>
</ Loggers>
</ Configuration>

4. 创建 Logger

直接使用 Log4j2 的 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( ...);

如果是配合 slf4j 使用也是可以的,只需要按照前面说的,提前做好适配,然后使用 slf4j 的 API 即可。

不过如果是新系统的话,建议直接上 Log4j2 的 API 吧,可以享受所有 Log4j2 的功能,使用 slf4j 之类的 API 时,上面说的参数格式化之类的功能就无法使用了。

5. 全异步配置

推荐配置 Log4j2 全异步(all async),在你的启动脚本中增加一个系统变量的配置。

Log4j2 由于拆分为 API 和实现两部分

2e08f26e3552fb606991bc9e6b2294ec.png

总结:几种日志框架 benchmark 对比结果(log4j2 官方测试结果):

2b47055a62e6dfb7f9a249809a0b28aa.png

从图上可以看出,Log4j2 的异步(全异步,非混合模式)下的性能,远超 Log4j1 和 Logback。

压力越大的情况下,吞吐上的差距就越大。在 64 线程测试下,Log4j2 的吞吐达到了 180w+/s,而 Logback/Log4j1 只有不到 20w,相差近十倍。

  • 16
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值