• 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再运行一次,如下所示。

  • 相关阅读:
    Gradle学习之基础篇
    springmvc上传文件方法及注意事项
    SpringCloud学习之feign
    SpringCloud学习之eureka集群配置
    SpringMvc+Spring+MyBatis 基于注解整合
    SpringBoot学习之SpringBoot执行器
    SpringBoot跨域问题解决方案
    SpringCloud学习之快速搭建分布式配置
    MySQL-Innodb存储结构
    PG-流复制
  • 原文地址:https://www.cnblogs.com/cherrie-lin/p/13427960.html
Copyright © 2020-2023  润新知