六品达通用权限系统__pd-tools-log

Posted 上善若水

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了六品达通用权限系统__pd-tools-log相关的知识,希望对你有一定的参考价值。

一、pd-tools-log

pd-tools-log模块定位为日子模块,本质也是一个starter。提供的日志功能主要有两个方面:

  1. 通过logback框架可以在控制台或者日志文件记录日志信息
  2. 拦截用户请求,将操作日志保存到数据库

pd-tools-log涉及到的技术点:

  1. 切面Aspect、切点PointCut、通知Advice
  2. Spring Event异步监听事件
  3. logback日志组件
  4. 函数式接口
  5. ThreadLocal

1.1、logback

1.1.1、logback介绍

Logback继承自log4jLogback的架构非常的通用,适用于不同的使用场景。

通过上图可以看到logbacklog4j都是slf4j规范的具体实现,我们在程序中直接调用的API其实都是slf4j的api,底层则是真正的日志实现组件—logback或者log4j
logback构建在三个主要的类上:LoggerAppenderLayout。这三个不同类型的组件一起作用能够让开发者根据消息的类型以及日志的级别来打印日志。
logback 作为日志的记录器,把它关联到应用的对应的context后,主要用于存放日志对象,也可以定义日志类型、级别。各个logger都被关联到一个LoggerContextLoggerContext负责制造logger,也负责以树结构排列各logger
Appender 主要用于指定日志输出的目的地,目的地可以是控制台、文件、数据库等。
Layout 负责把事件转换成字符串,输出格式化的日志信息。

logback的maven坐标:

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

1.1.2、logback层级

logback中每一个logger都依附在LoggerContext上,它负责产生logger,并且通过一个树状的层级结构来进行管理。
一个Logger被当作为一个实体,它们的命名是大小写敏感的,并且遵循以下规则:
如果一个logger的名字加上一个.作为另一个logger名字的前缀,那么该logger就是另一个logger的祖先。如果一个logger与另一个logger之间没有其它的logger,则该logger就是另一个logger的父级。

举例:
名为com.xbmu的logger是名为com.xbmu.service的logger的父级。
名为com的logger是名为com.xbmu的logger的父级,是名为com.xbmu.service的logger的祖先。

1.1.3、logback日志输出等级

logback的日志输出等级分为:TRACE, DEBUG, INFO, WARN, ERROR
如果一个给定的logger没有指定一个日志输出等级,那么它就会继承离它最近的一个祖先的层级。
为了确保所有的logger都有一个日志输出等级,root logger会有一个默认输出等级 — DEBUG。

1.1.4、logback初始化步骤

  1. logback会在类路径下寻找名为logback-test.xml的文件
  2. 如果没有找到,logback会继续寻找名为logback.groovy的文件
  3. 如果没有找到,logback会继续寻找名为logback.xml的文件
  4. 如果没有找到,将会在类路径下寻找文件META-INFO/services/ch.qos.logback.classic.spi.Configurator,该文件的内容为实现了Configurator接口的实现类的全限定类名
  5. 如果以上都没有成功,logback会通过BasicConfigurator为自己进行配置,并且日志将会全部在控制台打印出来

最后一步的目的是为了保证在所有的配置文件都没有被找到的情况下,提供一个默认的配置。

1.1.5、logback入门案例

1.1.5.1、案例一

本案例是一个logback简单应用,并且不提供配置文件而使用其提供的默认配置。
第一步:创建maven工程logback_demo并配置pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.xbmu</groupId>
    <artifactId>logback_demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
</project>

第二步:编写单元测试

package com.xbmu.test;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.util.StatusPrinter;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * logback使用方法
 */
public class LogbackTest 
    //简单使用
    @Test
    public void test1()
        Logger logger = LoggerFactory.getLogger("com.xbmu.logback.HelloWorld");
        logger.debug("debug ...");
    

    //打印日志内部状态
    @Test
    public void test2()
        Logger logger = LoggerFactory.getLogger("com.xbmu.logback.HelloWorld");
        logger.debug("debug ...");
        // 打印内部的状态
        LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();
        StatusPrinter.print(lc);
    

    /*
     * 日志输出级别:ERROR > WARN > INFO > DEBUG > TRACE
     * */

    //测试默认的日志输出级别
    @Test
    public void test3()
        Logger logger = LoggerFactory.getLogger("com.xbmu.logback.HelloWorld");
        logger.error("error ...");
        logger.warn("warn ...");
        logger.info("info ...");
        logger.debug("debug ...");
        //因为默认的输出级别为debug,所以这一条日志不会输出
        logger.trace("trace ...");
    

    //设置日志输出级别
    @Test
    public void test4()
        ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("com.xbmu.logback.HelloWorld");
        logger.setLevel(Level.WARN);
        logger.error("error ...");
        logger.warn("warn ...");
        logger.info("info ...");
        logger.debug("debug ...");
        logger.trace("trace ...");
    

    //测试Logger的继承
    @Test
    public void test5()
        ch.qos.logback.classic.Logger logger =
                (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("com.xbmu");
        logger.setLevel(Level.INFO);
        logger.error("error ...");
        logger.warn("warn ...");
        logger.info("info ...");
        logger.debug("debug ...");
        logger.trace("trace ...");

        // "com.xbmu.logback" 会继承 "com.xbmu" 的有效级别
        Logger barLogger = LoggerFactory.getLogger("com.xbmu.logback");
        // 这条日志会打印,因为 INFO >= INFO
        barLogger.info("子级信息");
        // 这条日志不会打印,因为 DEBUG < INFO
        barLogger.debug("子级调试信息");
    

    //Logger获取,根据同一个名称获得的logger都是同一个实例
    @Test
    public void test6()
        Logger logger1 = LoggerFactory.getLogger("com.xbmu");
        Logger logger2 = LoggerFactory.getLogger("com.xbmu");
        System.out.println(logger1 == logger2);
    

    //参数化日志
    @Test
    public void test7()
        Logger logger = LoggerFactory.getLogger("com.xbmu");
        logger.debug("hello ","world");
    

1.1.5.2、案例二

本案例是logback中Spring Boot项目中的应用。
第一步:创建maven工程springboot_logback_demo并配置pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/>
    </parent>

    <groupId>com.xbmu</groupId>
    <artifactId>springboot_logback_demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
     
</project>

第二步:在resources下编写logback配置文件logback-base.xmllogback-spring.xml
logback-base.xml

<?xml version="1.0" encoding="UTF-8"?>
<included>
    <contextName>logback</contextName>
    <!-- 
		name的值是变量的名称,value的值时变量定义的值
		定义变量后,可以使“$”来使用变量
	-->
    <property name="log.path" value="d:\\\\logs" />

    <!-- 彩色日志 -->
    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule
            conversionWord="clr"
            converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule
            conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
    <!-- 彩色日志格式 -->
    <property name="CONSOLE_LOG_PATTERN" value="$CONSOLE_LOG_PATTERN:-%clr(%dyyyy-MM-dd HH:mm:ss.SSS)faint %clr($LOG_LEVEL_PATTERN:-%5p) %clr($PID:- )magenta %clr(---)faint %clr([%15.15t])faint %clr(%-40.40logger39)cyan %clr(:)faint %m%n$LOG_EXCEPTION_CONVERSION_WORD:-%wEx"/>

    <!--输出到控制台-->
    <appender name="LOG_CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <Pattern>$CONSOLE_LOG_PATTERN</Pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!--输出到文件-->
    <appender name="LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>$log.path/logback.log</file>
        <!--日志文件输出格式-->
        <encoder>
            <pattern>%dyyyy-MM-dd HH:mm:ss.SSS [%thread] %-5level %logger50 - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日志归档路径以及格式 -->
            <fileNamePattern>$log.path/info/log-info-%dyyyy-MM-dd.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
    </appender>
</included>

logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--引入其他配置文件-->
    <include resource="logback-base.xml" />
    <!--
    <logger>用来设置某一个包或者具体的某一个类的日志打印级别、
    以及指定<appender>。<logger>仅有一个name属性,
    一个可选的level和一个可选的addtivity属性。
    name:用来指定受此logger约束的某一个包或者具体的某一个类。
    level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
          如果未设置此属性,那么当前logger将会继承上级的级别。
    addtivity:是否向上级logger传递打印信息。默认是true。
     -->

    <!--开发环境-->
    <springProfile name="dev">
        <logger name="com.xbmu.controller" additivity="false" level="debug">
            <appender-ref ref="LOG_CONSOLE"/>
        </logger>
    </springProfile>
    <!--生产环境-->
    <springProfile name="pro">
        <logger name="com.xbmu.controller" additivity="false" level="info">
            <appender-ref ref="LOG_FILE"/>
        </logger>
    </springProfile>

    <!--
    root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
    level:设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF 默认是DEBUG
    可以包含零个或多个元素,标识这个appender将会添加到这个logger。
    -->
    <root level="info">
        <appender-ref ref="LOG_CONSOLE" />
        <appender-ref ref="LOG_FILE" />
    </root>
</configuration>

第三步:编写application.yml

server:
  port: 9000
logging:
  #在Spring Boot项目中默认加载类路径下的logback-spring.xml文件
  config: classpath:logback-spring.xml
spring:
  profiles:
    active: dev

第四步:创建UserController

package com.xbmu.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController以上是关于六品达通用权限系统__pd-tools-log的主要内容,如果未能解决你的问题,请参考以下文章

六品达通用权限系统__pd-tools-log

二品达通用权限系统__项目搭建

二品达通用权限系统__项目搭建

二品达通用权限系统__项目搭建

三品达通用权限系统__pd-tools-swagger2

三品达通用权限系统__pd-tools-swagger2