Log日志


一、对比

Logger

Java util Logger是java原生的日志生成工具,不需要另外引用类库,使用方便,学习简单,能够在小型应用中灵活使用。

commons-logging

apache最早提供的日志的门面接口。避免和具体的日志方案直接耦合。类似于JDBC 的api 接口,具体的的JDBC driver 实现由各数据库提供商实现。通过统一接口解耦,不过其内部也实现了一些简单日志方案。

Log4j

Logging for Java,经典的一种日志解决方案。内部把日志系统抽象封装成Logger 、appender 、pattern 等实现。我们可以通过配置文件轻松的实现日志系统的管理和多样化配置。

slf4j

全称为Simple Logging Facade for Java。 是对不同日志框架提供的一个门面封装。可以在部署的时候不修改任何配置即可接入一种日志实现方案。和commons-loging 类似。个人感觉设从计上更好一些,没有commons 那么多潜规则。同时有两个额外特点:①能支持多个参数,并通过{}占位符进行替换,避免老写logger.isXXXEnabled这种无奈的判断,带来性能提升见;②OSGI机制更好兼容支持。

logback

作为一个通用可靠、快速灵活的日志框架,将作为Log4j 的替代和slf4j 组成新的日志系统的完整实现。具有极佳的性能,在关键路径上执行速度是log4j 的10 倍,且内存消耗更少。

Log4j2

Log4j2是Log4j的升级版,与之前的版本Log4j 1.x相比、有重大的改进,在修正了Logback固有的架构问题的同时,改进了许多Logback所具有的功能。

可以这么理解,slf4j和commons-logging是一种抽象接口,Log4j、Log4j2和logback是它们的实现,在实际使用中,一般选择slf4j+Log4j2或者slf4j+logback。

二、slf4j

为什么要使用slf4j

我们为什么要使用slf4j,举个例子:

我们自己的系统中使用了logback这个日志系统
我们的系统使用了A.jar,A.jar中使用的日志系统为log4j
我们的系统又使用了B.jar,B.jar中使用的日志系统为slf4j-simple

这样,我们的系统就不得不同时支持并维护logback、log4j、slf4j-simple三种日志框架,非常不便。

解决这个问题的方式就是引入一个适配层,由适配层决定使用哪一种日志系统,而调用端只需要做的事情就是打印日志而不需要关心如何打印日志,slf4j或者commons-logging就是这种适配层。

从上面的描述,我们必须清楚地知道一点:slf4j只是一个日志标准,并不是日志系统的具体实现。理解这句话非常重要,slf4j只做两件事情:

  • 提供日志接口
  • 提供获取具体日志对象的方法

slf4j-simple、logback都是slf4j的具体实现,log4j并不直接实现slf4j,但是有专门的一层桥接slf4j-log4j12来实现slf4j。

slf4j日志级别

  • trace
  • debug
  • info
  • warn
  • error

slf4j + logback

依赖

Spring 环境需要slf4j以及它的实现(slf4j-api + logback)和lombok依赖

Spring Boot 环境默认加入了slf4j-api和logback的依赖,所以只需要添加lombok的依赖即可

IDEA需要安装lombok插件

pom引入依赖

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.24</version>
</dependency>

配置logback

logback在启动时,根据以下步骤寻找配置文件:①在classpath中寻找logback-test.xml文件→②如果找不到logback-test.xml,则在 classpath中寻找logback.groovy文件→③如果找不到 logback.groovy,则在classpath中寻找logback.xml文件
如果上述的文件都找不到,则logback会使用JDK的SPI机制查找 META-INF/services/ch.qos.logback.classic.spi.Configurator中的 logback 配置实现类,这个实现类必须实现Configuration接口,使用它的实现来进行配置
如果上述操作都不成功,logback 就会使用它自带的 BasicConfigurator 来配置,并将日志输出到console。

这里采用xml格式的配置文件:在resources目录下新建logback.xml文件,logback.xml文件的具体配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
    <!--定义日志文件的存储地址 -->
    <property name="LOG_HOME" value="logs"/>

    <property name="COLOR_PATTERN"
              value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta( %replace(%caller{1}){'\t|Caller.{1}0|\r\n', ''})- %gray(%msg%xEx%n)"/>

    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <!-- 控制台输出 -->

    <!-- 按照每天生成日志文件 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志文档输出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset> <!-- 设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志归档 -->
            <fileNamePattern>${LOG_HOME}/log_%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文档保留天数-->
            <maxHistory>2</maxHistory>
        </rollingPolicy>
    </appender>
    <!-- 按照每天生成日志文件 -->

    <!--2. 输出到文档-->
    <!-- 2.1 level为 DEBUG 日志,时间滚动输出  -->
    <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文档的路径及文档名 -->
        <file>${LOG_HOME}/log_debug.log</file>
        <!--日志文档输出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset> <!-- 设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志归档 -->
            <fileNamePattern>${LOG_HOME}/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文档保留天数-->
            <maxHistory>2</maxHistory>
        </rollingPolicy>
        <!-- 此日志文档只记录debug级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUG</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 2.2 level为 INFO 日志,时间滚动输出  -->
    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文档的路径及文档名 -->
        <file>${LOG_HOME}/log_info.log</file>
        <!--日志文档输出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日志归档路径以及格式 -->
            <fileNamePattern>${LOG_HOME}/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文档保留天数-->
            <maxHistory>2</maxHistory>
        </rollingPolicy>
        <!-- 此日志文档只记录info级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 2.3 level为 WARN 日志,时间滚动输出  -->
    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文档的路径及文档名 -->
        <file>${LOG_HOME}/log_warn.log</file>
        <!--日志文档输出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文档保留天数-->
            <maxHistory>2</maxHistory>
        </rollingPolicy>
        <!-- 此日志文档只记录warn级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>warn</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 2.4 level为 ERROR 日志,时间滚动输出  -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文档的路径及文档名 -->
        <file>${LOG_HOME}/log_error.log</file>
        <!--日志文档输出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文档保留天数-->
            <maxHistory>2</maxHistory>
        </rollingPolicy>
        <!-- 此日志文档只记录ERROR级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>


    <!-- 生成html格式日志开始 -->
    <!--<appender name="HTML" class="ch.qos.logback.core.FileAppender">-->
    <!--&lt;!&ndash; 过滤器,只记录WARN级别的日志 &ndash;&gt;-->
    <!--&lt;!&ndash; <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>info</level>-->
    <!--<onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> &ndash;&gt;-->

    <!--<encoder-->
    <!--class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">-->
    <!--<layout class="ch.qos.logback.classic.html.HTMLLayout">-->
    <!--<pattern>%p%d%msg%M%F{32}%L</pattern>-->
    <!--</layout>-->
    <!--</encoder>-->
    <!--<file>${LOG_HOME}/error-log.html</file>-->
    <!--</appender>-->
    <!-- 生成html格式日志结束 -->

    <!-- 每天生成一个html格式的日志开始 -->
    <!--<appender name="FILE_HTML"-->
    <!--class="ch.qos.logback.core.rolling.RollingFileAppender">-->
    <!--<rollingPolicy-->
    <!--class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">-->
    <!--&lt;!&ndash;日志文件输出的文件名 &ndash;&gt;-->
    <!--<FileNamePattern>${LOG_HOME}/insight-product.%d{yyyy-MM-dd}.html-->
    <!--</FileNamePattern>-->
    <!--&lt;!&ndash;日志文件保留天数 &ndash;&gt;-->
    <!--<MaxHistory>15</MaxHistory>-->
    <!--</rollingPolicy>-->
    <!--<encoder-->
    <!--class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">-->
    <!--<layout class="ch.qos.logback.classic.html.HTMLLayout">-->
    <!--<pattern>%p%d%msg%M%F{32}%L</pattern>-->
    <!--</layout>-->
    <!--</encoder>-->
    <!--&lt;!&ndash;日志文件最大的大小 &ndash;&gt;-->
    <!--<triggeringPolicy-->
    <!--class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">-->
    <!--<MaxFileSize>10MB</MaxFileSize>-->
    <!--</triggeringPolicy>-->
    <!--</appender>-->
    <!-- 每天生成一个html格式的日志结束 -->

    <!--myibatis log configure -->
    <logger name="com.apache.ibatis" level="TRACE"/>
    <logger name="java.sql.Connection" level="DEBUG"/>
    <logger name="java.sql.Statement" level="DEBUG"/>
    <logger name="java.sql.PreparedStatement" level="DEBUG"/>

    <!-- 日志输出级别 -->
    <root level="INFO">
        <appender-ref ref="STDOUT"/>
        <!--<appender-ref ref="FILE"/>-->
        <appender-ref ref="ERROR_FILE"/>
        <!--<appender-ref ref="WARN_FILE"/>-->
        <appender-ref ref="INFO_FILE"/>
        <!--<appender-ref ref="DEBUG_FILE"/>-->
        <!--<appender-ref ref="HTML" />-->
        <!--<appender-ref ref="FILE_HTML" />-->
    </root>

</configuration>

使用

package com.example.springbootdemo.test;

import lombok.extern.slf4j.Slf4j;

/**
 * Slf4jTest
 *
 * @author: wcx
 * @date: 2022年06月16日 16:56
 */
@Slf4j
public class Slf4jTest {

    public static void main(String[] args) {
        log.info("Slf4jTest");
        log.info("Slf4jTest:{}","占位符test");
    }
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值