欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java日志框架详解总结(含配置)

程序员文章站 2022-05-24 15:30:13
...

该篇是集合了百度众多的日志框架详解,java日志框架分析的总结篇。
具体网址:

https://blog.csdn.net/foreverling/article/details/51385128
https://blog.csdn.net/chszs/article/details/8653460
http://baijiahao.baidu.com/s?id=1585361583532845302&wfr=spider&for=pc
http://www.importnew.com/28541.html
https://blog.csdn.net/victor_cindy1/article/details/78716917
https://zhuanlan.zhihu.com/p/24275518
https://my.oschina.net/aiguozhe/blog/87981
http://www.importnew.com/28541.html
https://blog.csdn.net/xktxoo/article/details/76359299

主要的就是这些了。
java里常见的日志库有java.util.logging(JDKlog)、Apache log4j、log4j2、logback、slf4j等等。
这么多的日志框架里如何选择。
首先需要梳理的是日志接口,以及日志接口对应的实现。然后再考虑如何选择使用哪个日志框架。
java日志框架详解总结(含配置)

java日志框架详解总结(含配置)

由图可知我们经常使用的日志框架实质上是一些接口的实现。而目前使用较广泛的统一日志规范接口就是slf4j和commons-logging。

slf4j

   它是基于API的java日志框架,slf4j提供了简单统一的日志记录的接口,开发者在配置部署
时只需要是吸纳这个接口就能是实现日志功能。它自身并没有提供具体的日志解决方案,它是负责
服务于各种各样的日志系统,允许用户在部署应用上使用自己常用的日志框架。
    也就是说,SLF4j是一个抽象层,它提供了众多的适配器能是配合其他所有开源日志框架。
为了考虑其他项目会使用大量的第三方库,而第三方库使用的日志框架又各不相同,不同的日志框
架又需要不同的配置,不同配置就会导致日志输出到不同的位置。所以我们就需要一个可以将日志
level、日志输出等统一管理,而slf4j的适配器又对各种日志都实现了接管,接管后就可以统一
配置这些第三方库中使用的日志。

commons-logging

commons-logging(jcl)也为众多日志实现库提供了统一的接口,作用和slf4j类似。它允许运行时绑定
任意的日志库。但commons-loggins对log4j和java.util.logging的配置问题兼容性不太好,还会
遇到类加载问题。所以当时log4j的作者又创作了slf4j.....

有了日志接口,就需要选择实现框架。在众多的日志框架如何选择

log4j

Log4j是apache下一个功能非常丰富的java日志库实现,Log4j应该是出现比较早而且最受欢迎的java
日志组件,它是基于java的开源的日志组件。Log4j的功能非常强大,通过Log4j可以把日志输出到控制
台、文件、用户界面。也可以输出到操作系统的事件记录器和一些系统常驻进程。值得一提的是:Log4j可
以允许你非常便捷地自定义日志格式和日志等级,可以帮助开发人员全方位的掌控自己的日志信息是一个日
志开源框架。

logback

logback是log4j的改进版本,而且原生支持slf4j(因为是同一作者开发)。所以logback+slf4j的组
合是日志框架的最佳选择。logback解决了log4j不能使用占位符的问题。logback可以通过jmx修改日
志配置,可以从jmx控制台直接操作,无需重启应用程序。它相比于log4j有更多的优点:

 - 原生实现了slf4j API(log4j需要中间层转换)
 - 支持xml、Groovy方式配置
 - 支持配置文件中加入条件判断
 - 更强大的过滤器
 - 更充分的测试
 - 更丰富的免费文档
 - 自动重载有变更的配置文件
 - 自动压缩历史日志
 等等

Log4j2

log4j2是log4j的升级版本2.x但并不兼容log4j因为它基本上把log4j版本的核心全部重构掉了,log4j2设计上很大程度模仿了slf4j-logback,性能也
获得了很大的提升。具体的差异自行百度。

至于网上不少说的性能比较,应该都是单个框架比较。但与slf4j绑定使用的话,怎么说都是logback性能最佳吧(猜测,欢迎指正)


日志级别

日志level定义应该遵循以下几个:

 - debug: 完整详细的记录流程的关键路径,用于开发人员比较感兴趣的跟踪和调试信息,生产环境中正常不会打开debug状态
 - info: 应简洁明确让管理员确定状态,记录相当重要有意义的信息。关键的系统参数的回显、后台服务的初始化状态、需要系统管理员确认的关键信息都需要使用info级别
 - warn: 能清楚告知发生了什么情况,指示潜在问题能引起别人重视,但不一定需要处理
 - error: 系统出现异常或不希望出现的问题,能及时得到关注处理。但也不是所有的异常都记录成error

根据上述,这里将以slf4j为日志接口,而其中logback与slf4j配合桥接性能最优,所以在日志实现上选择logback。
此处以maven进行管理,首先引入依赖,这两个依赖就够了,版本可根据需求修改

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.22</version>
    </dependency>
     <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.1.6</version>
    </dependency>

classpath中编写logback的配置文件logback.xml, logback.xml文件放在/src/main/resources/路径中

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- 
scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。 
scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
-->
<configuration scan="true" scanPeriod="60 seconds" debug="false">

    <!-- 上下文变量设置,用来定义变量值,其中name的值是变量的名称,value的值时变量定义的值。
        通过<property>定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
    <property name="CONTEXT_NAME" value="logback-test" />

    <!-- 上下文名称:<contextName>, 每个logger都关联到logger上下文,
        默认上下文名称为“default”。但可以使用<contextName>设置成其他名字,用于区分不同应用程序的记录。
        一旦设置,不能修改。 -->
    <contextName>${CONTEXT_NAME}</contextName>

    <!-- <appender>是<configuration>的子节点,是负责写日志的组件。
        有两个必要属性name和class。
        name指定appender名称,
        class指定appender的实现类。 -->
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 对日志进行格式化。 -->
        <encoder>
            <pattern>
                %d{yyyy-MM-dd HH:mm:ss.SSS}|%level|%class|%thread|%method|%line|%msg%n
            </pattern>
        </encoder>
    </appender>

    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 被写入的文件名,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建,没有默认值。 -->
        <file>${logs.dir}/logback-test.log</file>

        <!-- 当发生滚动时的行为  -->
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <!-- 必须包含“%i”例如,假设最小值和最大值分别为1和2,命名模式为 mylog%i.log,会产生归档文件mylog1.log和mylog2.log。还可以指定文件压缩选项,例如,mylog%i.log.gz 或者 没有log%i.log.zip -->
            <FileNamePattern>${logs.dir}/logback-test.%i.log</FileNamePattern>
            <!-- 窗口索引最小值 -->
            <minIndex>1</minIndex>
            <!-- 窗口索引最大值 -->
            <maxIndex>1</maxIndex>
        </rollingPolicy>

        <!-- **滚动的条件。 -->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <!-- 活动文件的大小,默认值是10MB -->
            <maxFileSize>30MB</maxFileSize>
        </triggeringPolicy>

        <!-- 对记录事件进行格式化。 -->
        <encoder>
            <charset>UTF-8</charset>
            <Pattern>
                %d{yyyy-MM-dd HH:mm:ss.SSS}|%level|%class|%thread|%method|%line|%msg%n
            </Pattern>
        </encoder>
    </appender>

    <!-- 特殊的<logger>元素,是根logger。只有一个level属性,应为已经被命名为"root".
        level:设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能设置为INHERITED或者同义词NULL。默认是DEBUG。
        <root>可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个loger。 -->
    <root>
        <level value="WARN" />
        <appender-ref ref="stdout" />
        <appender-ref ref="file" />
    </root>

    <!-- 用来设置某一个 包 或者具体的某一个 类 的日志打印级别、以及指定<appender>, 
        name:用来指定受此logger约束的某一个包或者具体的某一个类。
        level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。如果未设置此属性,那么当前loger将会继承上级的级别。 
        additivity:是否向上级logger传递打印信息。默认是true。(这个logger的上级就是上面的root)
        <logger>可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个logger。-->
    <logger name="xuyihao.logback.test" level="DEBUG" additivity="true"></logger>

</configuration>