6、SpringBoot - 日志配置

01、项目日志格式

Spring Boot 的默认日志输出类似于以下示例:

2021-12-14 22:40:14.159  INFO 20132 --- [           main] com.kuangstudy.SpringbootApplication     : Started SpringbootApplication in 2.466 seconds (JVM running for 3.617)

输出以下项目:

  • 日期和时间:毫秒精度且易于排序。
  • 日志级别:ERRORWARNINFODEBUG,或TRACE
  • 进程标识。
  • 一个---分离器来区分实际日志消息的开始。
  • 线程名称:括在方括号中(可能会被截断以用于控制台输出)。
  • 记录器名称:这通常是源类名称(通常缩写)。
  • 日志消息。
  • 换行符

注意:Logback 没有FATAL级别。它被映射到ERROR.

02、流行的日志框架

  • Java Util Logging
  • Logging
  • Log4j2
  • Logback(默认)

在这里插入图片描述

从上图中分析得出 springboot的底层spring-boot-starter-logging可以看出,它依赖的3个日志框架:slf4j(父类)、Logback(实现类)、Log4j2 (实现类)。它们的区别是:

  • logback和log4j是日志实现框架,就是实现怎么记录日志的。
  • slf4j-api提供了java所有日志框架的简单规范和标准(日志的门面设计模式), 说白了就是一个日志API(没有实现类,里面全是接口),它不能单独使用:故必须结合logback和Log4j2 日志框架来实现。
  • springboot的日志搭配。
    • spring2.0默认采用slf4j-api + logback的日志搭配,在开发过程中,我们都是采用slf4j的api去记录日志,底层的实现就是根据配置logback和Log4j2 日志框架。

03、Log4j2配置

先来了解一下Log4j2的发展史:

Apache Log4j2 是Log4j的一个升级版本,但是不仅仅是升级,几乎完全进行了重构。旧版本的Log4j,自2015年5月以后就停止对它的更新了。Log4j2是高效的,低延迟的异步日志处理框架,在多线程的场景中,Log4j2的性能是Log4j、LogBack和Logging日志吞吐量的18倍。如何整合如下:

03-01、配置

<!--springboot的web的starter-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <!-- 排除掉默认的logging,引入log4j2 -->
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

一般不使用log4j2,一般都是直接引用Lombok,或者直接配置logback.xml文件

03-02、Lombok的日志的定义

支持:@Slf4j (logback) 和 @Log4j2 (log4j2)

推荐使用:@Slf4j

springboot的日志支持
<!--springboot的web的starter-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

我们依赖的web中已经包含了日志logging如下:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-logging</artifactId>
    <version>2.5.7</version>
    <scope>compile</scope>
</dependency>

默认情况:springboot默认日志是:logback

传统的定义日志

在每个类中定义日志

private final static Logger log = LoggerFactory.getLogger(AlipayController.class);
private final static Logger log = LoggerFactory.getLogger(LoggerController.class);

使用

 log.info("-----info--------");
Lombok的定义日志
package com.kuangstudy.web.log;

import lombok.AllArgsConstructor;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Description:
 * Author: yandi Administrator
 * Version: 1.0
 * Create Date Time: 2021/12/14 15:31.
 * Update Date Time:
 *
 * @see
 */
@RestController
@Slf4j
public class LoggerController {
//    private final static Logger log = LoggerFactory.getLogger(LoggerController.class);
    @GetMapping("/log1")
    public String log1() {
        log.info("-----info--------");
        return "log1";
    }
}
  • 在每个需要增加日志的类上增加注解:@Log4j2 或者 @Slf4j
  • 然后在需要打印日志的方法上,通过log对象就去输入日志。

04、LogBack配置(默认)

概述分析

默认情况下,如果您使用“Starters”,则使用 Logback 进行日志记录。还包括适当的 Logback 路由,以确保使用 Java Util Logging、Commons Logging、Log4J 或 SLF4J 的依赖库都能正常工作。

具体操作如下:

package com.kuangstudy.web.log;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Description:
 * Author: yandi Administrator
 * Version: 1.0
 * Create Date Time: 2021/12/14 15:31.
 * Update Date Time:
 *
 * @see
 */
@RestController
public class LoggerController {

    private final static Logger log = LoggerFactory.getLogger(LoggerController.class);


    @GetMapping("/log1")
    public String log1() {
        log.trace("--------------------trace");
        log.debug("--------------------debug");
        log.info("--------------------info");
        log.warn("--------------------warn");
        log.error("--------------------error");
        return "log1";
    }
}

打印可以看出来只打印了:

2021-12-14 15:33:59.473  INFO 15424 --- [nio-8083-exec-1] com.kuangstudy.web.log.LoggerController  : --------------------info
2021-12-14 15:33:59.474  WARN 15424 --- [nio-8083-exec-1] com.kuangstudy.web.log.LoggerController  : --------------------warn
2021-12-14 15:33:59.474 ERROR 15424 --- [nio-8083-exec-1] com.kuangstudy.web.log.LoggerController  : --------------------error

因为默认情况下:springboot的默认日志级别是:info

# 修改日志级别
logging:
  level:
    root: info

可以在application.yml配置如下:

# 指定包的日志级别logging:  level:    com.kuangstudy.web.log: trace

打印如下:

36:38.651 TRACE 4208 --- [nio-8083-exec-1] com.kuangstudy.web.log.LoggerController  : --------------------trace2021-12-14 15:36:38.651 DEBUG 4208 --- [nio-8083-exec-1] com.kuangstudy.web.log.LoggerController  : --------------------debug2021-12-14 15:36:38.651  INFO 4208 --- [nio-8083-exec-1] com.kuangstudy.web.log.LoggerController  : --------------------info2021-12-14 15:36:38.651  WARN 4208 --- [nio-8083-exec-1] com.kuangstudy.web.log.LoggerController  : --------------------warn2021-12-14 15:36:38.651 ERROR 4208 --- [nio-8083-exec-1] com.kuangstudy.web.log.LoggerController  : --------------------error

总结

  • debug是开发首选,是一种明细的日志级别,可以看到框架加载类的所有过程,如果你要进行源码分析,查看SQL执行的过程,框架的执行的过程,肯定是用debug

    # 修改日志级别logging:  level:    root: debug    com.kuang.order: info
    
  • info: 只会打印常见的日志信息

  • error: 只会打印错误日志信息,一般在生产环境中进行设定。因为项目开发测试完毕,肯定在线上肯定只关注错误,如果你其他也关注,可以单独设定。

    # 修改日志级别logging:  level:    root: error    com.kuang.order: info
    

05、springboot具体配置日志

默认springboot的日志是:logback , 但是只会输出Error、Warn和Info级别的日志信息。可以修改日志的级别来控制:

05-01、日志级别

logging:
  level: 
    # 设置日志的默认级别为 info
    root: info
    # 设置com.kuantstudy.log包下的日志级别是 debug
    com.kuantstudy.log: debug

05-02、日志文件

在实际开发中,特别是在生产环境中,你不可能一直看着控制台,而且日志会非常的大,瞬间就丢失了。因此我们需要把日志存储在指定的目录或者文件中:

指令目录输入日志文件(不推荐)

告诉springboot使用logback生成的日志,除了在控制打印一份,同时往这个目录outputs/logs的中生成一个spring.log文件中生成一份。

一句话:目录的指定,只是告诉spring.log放在哪里。

logging:  # 指定日志输出的目录  file:    path: outputs/logs

如下:

在这里插入图片描述

指定以后,会默认生成 spring.log 文件

指定日志文件输出(推荐)
logging:  file:    name: G://outputs/logs/springboot.log

在这里插入图片描述

06、完整的logback-spring.xml

06-01、application-dev.yml配置

myapp:
  logpath: G:/logs/springboot/

06-02、application-prod.yml配置

myapp:
  logpath: /logs/springboot/

06-03、logback-spring-xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <springProperty scope="context" name="LOG_PATH" source="myapp.logpath" defaultValue="mylogxxxx"/>
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
    <!-- 文件日期滚动记录 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--初始文件名-->
        <file>${LOG_PATH}/log_file.log</file>
        <!--日志是否追加 true-->
        <append>true</append>
        <!--可以支持并发-->
        <prudent>true</prudent>
        <!--开始定义日志的回滚策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件每天生成的格式是-->
            <fileNamePattern>${LOG_PATH}/log_file_%d{yyyy-mm-dd.HH.MM}.log</fileNamePattern>
            <!-- maxHistory日志保留时长,30天或者30分钟,看上面的格式是怎么设置的(现在是分钟)。超过天数后删除日志文件,同时配套目录一起删除。该参数不一定是指天数,也可以是月份数。
            具体参考滚动规则fileNamePattern,看是依赖什么进行滚动的-->
            <maxHistory>30</maxHistory>
            <!-- totalSizeCap最大日志量-->
            <totalSizeCap>100MB</totalSizeCap>
        </rollingPolicy>
        <!--滚动触发规则-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <!--maxFileSize单个文件最大量,如果达到这个最大量。日志有可能会出现报错,新日志无法存入。-->
            <maxFileSize>1MB</maxFileSize>
        </triggeringPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>【FILE】 %green(%d{yyyy-MM-dd HH:mm:ss:SSS}) [%thread] [%-5level] %logger %M %L - %msg%n</pattern>
        </encoder>
        <!-- 把error以下级别的日志过滤掉  info < warn <error  -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
    </appender>

    <!--日志异步到数据库,连接数据库,数据库中药创建相应的表  -->
    <appender name="DBAPPENDER" class="ch.qos.logback.classic.db.DBAppender">
        <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
            <dataSource class="com.zaxxer.hikari.HikariDataSource">
                <driverClassName>com.mysql.jdbc.Driver</driverClassName>
                <jdbcUrl>jdbc:mysql://localhost:3306/kss-web-db?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false</jdbcUrl>
                <username>root</username>
                <password>mkxiaoer</password>
                <poolName>HikariPool-logback</poolName>
            </dataSource>
        </connectionSource>
    </appender>

    <!-- 控制台 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!--格式化输出:%d:表示日期    %thread:表示线程名     %-5level:级别从左显示5个字符宽度  %msg:日志消息    %n:是换行符-->
            <pattern>【KSD - CONSOLE】 %clr(%d{yyyy-MM-dd HH:mm:ss:SSS}){yellow} %clr([%thread]){green} %blue([%-5level]) %logger %M %L - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 把error以下级别的日志过滤掉  info < warn <error  -->
<!--        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">-->
<!--            <level>ERROR</level>-->
<!--            <level>INFO</level>-->
<!--        </filter>-->
    </appender>

    <!-- 把日志异步输出到磁盘文件中,避免每次都进行磁盘IO操作,(每次100条写入一次) -->
    <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
        <discardingThreshold>0</discardingThreshold>
        <queueSize>100</queueSize>
        <appender-ref ref="FILE" />
    </appender>

    <!-- 不同的环境不同的配置 dev -->
    <springProfile name="dev">
        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
        </root>
    </springProfile>

    <!-- 不同的环境不同的配置 prod -->
    <springProfile name="prod">
        <root level="ERROR">
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="ASYNC"/>
            <appender-ref ref="DBAPPENDER"/>
        </root>
         <!-- 指定包的级别 -->
        <logger name="com.kuangstudy.order" level="INFO">
            <appender-ref ref="FILE"/>
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="DBAPPENDER"/>
        </logger>
    </springProfile>
</configuration>

06-04、日志入库应该创建的表

BEGIN;
DROP TABLE IF EXISTS logging_event_property;
DROP TABLE IF EXISTS logging_event_exception;
DROP TABLE IF EXISTS logging_event;
COMMIT;


BEGIN;
CREATE TABLE logging_event 
  (
    timestmp         BIGINT NOT NULL,
    formatted_message  TEXT NOT NULL,
    logger_name       VARCHAR(254) NOT NULL,
    level_string      VARCHAR(254) NOT NULL,
    thread_name       VARCHAR(254),
    reference_flag    SMALLINT,
    arg0              VARCHAR(254),
    arg1              VARCHAR(254),
    arg2              VARCHAR(254),
    arg3              VARCHAR(254),
    caller_filename   VARCHAR(254) NOT NULL,
    caller_class      VARCHAR(254) NOT NULL,
    caller_method     VARCHAR(254) NOT NULL,
    caller_line       CHAR(4) NOT NULL,
    event_id          BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY
  );
COMMIT;

BEGIN;
CREATE TABLE logging_event_property
  (
    event_id          BIGINT NOT NULL,
    mapped_key        VARCHAR(254) NOT NULL,
    mapped_value      TEXT,
    PRIMARY KEY(event_id, mapped_key),
    FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
  );
COMMIT;

BEGIN;
CREATE TABLE logging_event_exception
  (
    event_id         BIGINT NOT NULL,
    i                SMALLINT NOT NULL,
    trace_line       VARCHAR(254) NOT NULL,
    PRIMARY KEY(event_id, i),
    FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
  );
COMMIT;
  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值