Skip to content

我们之前打印日志都是采用sout的方式来输出日志, 这种日志方式有如下缺点:

  1. 不能开关式控制日志的输出
  2. 不能持久化存储日志的信息
  3. 不能分级别输出日志
  4. 采用的是当前线程来进行日期输出, 会阻塞当前线程其他任务

市面上其实有很多的日志框架, 其中logback日志框架, 是目前比较主流的框架, 解决了如上问题, 他提供日志输出的对象, 让我们可以以指定级别方式进行输出日志, 并且可以通过配置文件来开关式控制日志指定级别的输出, 还能够设置日志的持久化存储的位置, 而且采用所有的日志输出都是采用的子线程的方式输出, 不会阻塞当前线程的任务,而springboot其实已经集成logback的相关的依赖, 我们可以通过注解就可以拿到该日志对象进行使用, 下面是使用步骤。

基本使用 ​

为了记录在Controller方法中接收的参数,我们来引入**Logback**来记录日志

在SpringBoot中使用Logback非常简单,只需要在类上添加一个@Slf4j注解,然后就可以在需要打印日志的方法直接调用log.info(), log.warn() ,log.error() 打印

java
@Slf4j
public class DeptController {

    public Result addDept(@RequestBody Dept dept) {
        log.info("新增部门,参数:{}",dept);
        deptService.addDept(dept);
        return Result.success();
    }
}

按照此语法,修改DeptController代码如下

java
package com.itheima.controller;

import com.itheima.common.PageResult;
import com.itheima.common.Result;
import com.itheima.entity.Dept;
import com.itheima.service.DeptService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * 部门管理
 */
@RestController
@Slf4j
public class DeptController {

    @Autowired
    private DeptService deptService;

    /**
     * 新增部门
     *
     * @param dept 部门信息
     * @return 操作结果
     */
    @PostMapping("/depts") //对应前端提交时用到的请求方式
    //当前端使用POST和PUT的请求体提交json根式的参数时,后端需要使用  @RequestBody 类对象   的方式接收
    public Result addDept(@RequestBody Dept dept) {
        log.info("新增部门,参数:{}", dept);
        deptService.addDept(dept);
        return Result.success();
    }

    /**
     * 条件分页查询部门
     *
     * @param name     部门名称
     * @param status   状态
     * @param page     页码
     * @param pageSize 每页记录数
     * @return 分页查询结果
     */
    @GetMapping("/depts") //接收前端发送的GET请求
    // 当前端使用(?参数)方式提交请求参数时, 后端需要使用@RequestParam注解(可以省略)接收参数
    // @RequestParam注解的defaultValue属性可以设置默认值
    public Result listDepts(String name, Integer status,
                            @RequestParam(defaultValue = "1") Integer page,
                            @RequestParam(defaultValue = "10") Integer pageSize) {
        log.info("分页查询部门, 参数: name={}, status={}, page={}, pageSize={}", name, status, page, pageSize);
        PageResult<Dept> pageResult = deptService.findDeptsByPage(name, status, page, pageSize);
        return Result.success(pageResult);
    }

    /**
     * 根据ID查询部门
     *
     * @param id 部门ID
     * @return 查询结果
     */
    @GetMapping("/depts/{id}")
    // 当前端使用(路径/)方式提交请求参数时, 后端需要使用@PathVariable注解接收参数
    public Result findById(@PathVariable Integer id) {
        log.info("查询部门ID为{}的部门信息", id);
        Dept dept = deptService.findById(id);
        return Result.success(dept);
    }

    /**
     * 修改部门
     *
     * @param dept 部门信息
     * @return 统一响应结果
     */
    @PutMapping("/depts")
    public Result updateDept(@RequestBody Dept dept) {
        log.info("修改部门信息:{}", dept);
        deptService.updateById(dept);
        return Result.success();
    }
    
    /**
     * 删除部门
     *
     * @param id 部门ID
     * @return 统一响应结果
     */
    @DeleteMapping("/depts/{id}")
    public Result deleteDept(@PathVariable("id") Integer id) {
        log.info("删除部门:{}", id);
        deptService.deleteById(id);
        return Result.success();
    }
}

总结

日志输出的格式:

  1. 单个变量的使用:log.info("新增部门的数据:{}", dept);
  2. 多个变量的使用:log.info("删除部门拿到的部门ID:{}, 用户ID: {}", id, userId);

相当于有几个需要log的变量就使用几个{}进行占位处理,后面按顺序存放在占位符中展示的变量。

配置文件 ​

Logback日志框架的配置文件叫 logback.xml 内容如下,通过它可以设置日志的输出格式、位置、级别,在下面的图示例的地方创建配置文件:

配置文件的内容如下:

xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--
        CONSOLE :表示当前的日志信息是可以输出到控制台的。
    -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>
               %d{yyyy-MM-dd HH:mm:ss} [%thread] %highlight(%-5level) %cyan(%logger{36}) - %magenta(%msg) \n
            </pattern>
        </encoder>
    </appender>

    <!-- File是输出的方向通向文件的 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg \n</pattern>
            <charset>utf-8</charset>
        </encoder>
        <!--日志输出路径,目录不存在则会自动创建,但是在Windows中,至少要保证盘符是正确的!!!-->
        <file>D:/code/qk-parent-logs/itheima-data.log</file>
        <!--指定日志文件拆分和压缩规则-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--通过指定压缩文件名称,来确定分割文件方式-->
            <fileNamePattern>D:/code/qk-parent-logs/itheima-data-%i-%d{yyyy-MM-dd}-.log.gz</fileNamePattern>
            <!--文件拆分大小-->
            <maxFileSize>1MB</maxFileSize>
            <!-- 日志保留天数 -->
            <maxHistory>7</maxHistory>
            <!-- 全部归档日志总和上限,防止 maxHistory 失效、磁盘打爆 -->
            <totalSizeCap>500MB</totalSizeCap>
        </rollingPolicy>
    </appender>
    <!--
        1、控制日志的输出情况:如,开启日志,取消日志
        off >  error > warn > info > debug > trace > all
        日志技术, 会输出配置级别以及比配置的级别要高的日志
        开发阶段一般配置info和debug以上的级别
        生成阶段则是error和warn级别
    -->
    <root level="info"> <!-- 表示输出大于等于info以上级别的日志 -->
        <!-- 日志输出的详细控制,name对应上面的CONSOLE和FILE配置 -->
        <!-- 输出到控制台 -->
        <appender-ref ref="CONSOLE"/>
        <!-- 存放到文件的配置 -->
        <appender-ref ref="FILE"/>
    </root>
</configuration>