logback详解

1. slf4j介绍

简单的讲就是slf4j是一系列的日志接口,而log4j、logback是具体实现了的日志框架。
因为是接口,所以在项目中如果你不引用log4j 、logback或者其它日志框架你会发现,控制台的输出是这样的

2. log4j和logback区别

log4j:是apache实现的一个开源日志组件。
logback:同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架。是slf4j的原生实现,也就是说logback实现slf4j是不消耗内存和计算开销的。
Logback替代log4J的十大理由:自行百度吧,总而言之,就是logback好用就对了。
以下是各种日志接口和SLF4J的关系。

unbound:未绑定的
underlying logging framework:底层日志框架
adaptation layer:适配层
native implementtation of a:a的本地实现
non-native implementation of a:非本地实现

3. logback介绍

Logback是由log4j创始人设计的又一个开源日志组件。Logback包括3个部分:
·logback-core(基础核心模块,其它两个模块的基础模块)
·logback-classic(log4j改良版,完整实现SLF4J API接口,可方便的与其他日志系统切换)
·logback-access(logback-access访问模块与Servlet容器集成提供通过Http访问日志的功能)

4.logback实际的使用

日常在开发的过程中,如果一个独立的模块(一个单独的完整的服务)涉及到好几个大的模块,比如用户管理模块,支付模块,订单模块,并且这几个模块日志很多,最好分开打印日志,这时候就需要分开成多个日志文件了,这时候需要怎么做呢?
(1) 文件的目录结构
三个模块:假设三个文件夹分别代表的是用户管理、支付、订单管理三个模块
Logs接口:各个模块日志的实现接口
配置文件:日志的回滚,基本配置在这里

(2)pom文件导入

这个包经常导入其它包的时候会导入,但是版本不是最新的,可以重新加依赖导一次
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.22</version>
</dependency>
<!--logback-classic包,该依赖会导入logback-core和logback-classic两个包-->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
</dependency>

<!--logback-core包-->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <version>1.2.3</version>
</dependency>

<!--logback-access包-->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-access</artifactId>
    <version>1.2.3</version>
</dependency>

(3)logback.xml详解

<?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>

(4)Logs接口的详细实现

public interface Logs {
    /**
     * 控制台打印
     */
    Logger CONSOLE = LoggerFactory.getLogger("console");

    /**
     * 用户相关的日志
     */
    Logger USER = LoggerFactory.getLogger("ssh.user.log");

    /**
     * 物流相关的日志
     */
    Logger LOGISTICS = LoggerFactory.getLogger("ssh.logistics.log");

    /**
     * 订单相关的日志
     */
    Logger ORDER = LoggerFactory.getLogger("ssh.order.log");
}

(5)实际应用

public class Logistics {
    private static final Logger LOGGER = LoggerFactory.getLogger(Logistics.class);

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            LOGGER.info("logistics common log");
            Logs.LOGISTICS.info("logistics special log");

        }
    }
}

public class User {
    private static final Logger LOGGER = LoggerFactory.getLogger(User.class);

    public static void main(String[] args) {
        LOGGER.info("user common log");
        Logs.USER.info("user special log");
    }
}

public class Order {
    private static final Logger LOGGER = LoggerFactory.getLogger(Order.class);

    public static void main(String[] args) {
        LOGGER.info("order common log");
        Logs.ORDER.info("order special log");
        LOGGER.debug("order debug");
        Logs.ORDER.info("order debug");

    }
}

(6)运行结果
第一次:运行Logistics.main,运行结束后发现在D盘会创建Log文件夹,并且按Logback的配置文件,创建四个模块的目录,并且每个模块的日志文件已经创建好,打印对应的日志,如下所示




第二次:再运行order.main

我们发现debug日志没有打印,所以此时我们将logback中对应的日志级别由info改为debug再运行一次,如下所示。

原文地址:https://www.cnblogs.com/cherrie-lin/p/13427960.html