【Spring】Spring Boot 日志(8)

本系列共涉及4个框架:Sping,SpringBoot,Spring MVC,Mybatis。

博客涉及框架的重要知识点,根据序号学习即可。

1、日志概述

1.1学习日志的必要性

在第一次学习编程语言的时候,我们就在使用printf或者System.out.println等打印语句打印日志了,为什么日志这么重要呢?因为在编程的学习过程中,不可能不出错,所以打印日志是最快来发现和定位问题的,或者说可以根据日志来分析程序的运行过程。

1.2日志的用途

(1)系统监控:在大数据时代,监控几乎是一个成熟系统了,我们可以通过日志记录这个系统的运行状态,响应状态,在关键时刻某规则超过了阈值则立马报警

(2)数据采集:日志可以采集数据为数据统计、推荐排序做出巨大贡献。【数据统计:统计某页面的浏览量(PV),访客量(UV),点击量等来优化公司运营策略】【推荐排序:目前推荐排序应用在各大领域,比如我们熟悉的抖音、拼多多等日流量爆炸的应用,点击推荐。数据采集是推荐排序工作中的非常重要的一步,系统通过日志记录用户的浏览历史,停留时间等,算法人员就会通过这些数据训练模型,给用户做推荐】

(3)日志审计:随着互联网的发展,越来越多的公司关键业务运行在网络在上,网络安全越来越受大家关注。通过日志分析,在公司中可以清楚的知道是谁做了某些违规操作,或者是信息泄露等等。

2、日志使用

2.1打印日志

(1)在SpringBoot项目启动时,就会有默认的日志打印,如下图所示,那么这些日志和System.out.println()打印的有什么区别呢?

可以知道System.out.println()只会打印括号里面的内容,相较于SpringBoot的打印少了很多信息。

然而SpringBoot内置了日志框架Slf4j,我们可以在程序中直接调用Slf4j来输出日志。

(2)打印日志的步骤:

①在程序中获取日志对象

②使用日志对象打印日志

注意:导包的时候别导错了!!!!Logger对象时属于org.slf4j包下的

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

@RestController
public class LoggerController {
    //在程序中获取日志对象需要使用日志工厂LoggerFactory
    //LoggerFactory.getLogger需要传递一个参数,标识这个日志的名称,这样可以更清晰的知道是哪个类输出的日志,更好定位
    private static Logger logger = LoggerFactory.getLogger(LoggerController.class);
    //使用日志对象打印日志,info()只是一种打印日志的方法
    @RequestMapping("/logger")
    public String logger(){
        logger.info("-------------要输出的日志------------");
        return "打印日志";
    }
}

2.2日志框架

(1)

(2)SLF4J不同于其他日志框架,它不是一个真正的日志实现,而是一个抽象层,对日志框架制定的一种规范,标准,接口。所有SLF4J并不能独立使用,需要和具体的日志框架配合使用。SLF4J就是其他日志框架的门面,可以理解为是提供日志服务事务统一API接口,并不涉及到具体的日志逻辑框架

(3)那么为什么要SLF4J当门面呢?而不直接使用日志框架(即具体的日志逻辑)。当然这肯定是有原因的------假如不引入日志门面,在开发某个项目时,已经使用了log4j,然而在功能的实现时,需要依赖另一个日志框架logback,那么你又要把logback也加载进去,这样导致的就是有两个日志框架共存,不好维护配置文件,更换日志框架时修改代码,修改的代码有冲突怎么办?所以这就体现出引入日志门面的好处了,引入之后,应用程序和日志框架之间有了统一的API接口,此时只需要维护一套日志文件配置,且当底层实现框架改变时,也不需要更改应用程序的代码了

2.3门面模式(外观模式)

(1)门面模式

①SLF4J是门面模式的典型应用(但是不仅仅使用了门面模式)

②定义:门面模式(Facade Pattern)又称为外观模式,提供了一个统一的接口,用来访问子系统中的一群接口。主要特征是定义了一个高层接口,让子系统更容易使用

③门面模式主要包含2种角色:

外观角色(Facade):也称门面角色,系统对外的统一接口

子系统角色(SubSystem):可以同时有一个或多个SubSystem。每个SubSystem都不是一个单独的类,而是一个类的集合。SubSystem并不知道Facade的存在,对于SubSystem而言,Facade知识另一个客户端而已(Facade对SubSystem透明)

(2)举例:

去教室自习,第一个进教室的人儿 一般先会开前灯,再开中灯,再开后灯,这样整个教室都亮了,以便更好的进行自习;自习结束时,最后一个人儿,会先关后灯,再关中灯,再关前灯后离开。

如果设置一个总开关,来控制整个教室的灯的开关就会很方便。

在这里,总灯就是外观角色,而前中后灯都是子系统角色。

(3)优点:

①减少了系统的相互依赖,实现了客户端与子系统的耦合关系,这使得子系统的变化不会影响到调用它的客户端

②提高了灵活性,简化了客户端对子系统的使用难度,客户端无需关心子系统的具体实现方式,而只需要和面向对象交互即可

③提高了安全性,可以林火设定访问权限,不在门面对象中开通方法,就无法访问




3、日志格式的说明

①时间日期:精确到秒

②日志级别

③进程ID

④线程名

⑤Logger名(通常使用源代码的类名)

⑥日志内容




4、日志级别

4.1日志级别的分类

(1)日志级别代表日志信息对应问题的严重性,为了更快的筛选符合目标的日志信息。有了日志级别就可以过滤自己想看到的信息了,比如只关注error级别的,就可以根据级别过滤出error级别的日志信息,节约开发者的信息筛选时间

(2)日志级别的分类:

日志的级别从高到低依次为:FATAL、ERROR、WARN、INFO、DEBUG、TRACE

①FATAL:致命信息,表示需要立即被处理的系统级错误

②ERROR:错误信息,级别较高的错误日志信息,但仍然不影响系统的继续进行

③WARN:警告信息,不影响使用,是需要注意的问题

④INFO:普通信息,用于记录应用程序正常运行的一些信息,例如系统启动完成、请求处理完成等

⑤DEBUG:调试信息,需要调试时候打印关键信息

⑥TRACE:追踪信息,比DEBUG更细粒度的信息事件(除非有特殊用意,否则请使用DEBUG代替)

4.2日志级别的使用

@RequestMapping("/printLog")
    public String printLog(){
        logger.trace("===trace===");
        logger.debug("===debug===");
        logger.info("===info===");
        logger.warn("===warn===");
        logger.error("===error===");
        return  "打印不同级别的日志";
    }

SpringBoot默认的日志框架是Logback,Logback没有fatal级别,它被映射到error。

观察运行结果,发现只打印了info、warn和error级别的日志,是因为日志的输出级别默认是info,所以只会打印大于等于info级别的日志,也就是info、warn、error。




5、日志配置

5.1配置日志级别

(1)Properties配置:

logger.level.root:debug

(2)yml配置:

logger:

level:

root:debug

5.2日志持久化

(1)开发环境上的日志都是输出到控制台上的,然而在线上环境中,我们需要把日志保存下来,以便出现问题之后追溯问题。把日志保存下来就叫做持久化。

(2)日志持久化的两种方式:

①配置日志文件名

Properties配置:

logger.file.name:logger/springboot.log

Yml配置:

logging:

file:

name:logger/springboot.log

[两者任选其一即可]

②配置日志的存储目录

Properties配置:

logger.file.path:D:/temp

Yml配置:

logging:

file:

path:D:/temp

[两者任选其一即可]

(3)当logger.file.name与logger.file.path两个都配置的情况下,只生效其一,以logger.file.name为准

5.3划分日志文件大小

(1)如果我们的日志都放在一个文件中,随着项目的运行,日志文件会越来越大,需要对文件进行分割。【当然日志框架也考虑到了,如果不进行配置,默认就是10M进行分割

(2)配置日志文件的分割:

①Properties配置:

复制代码
logging.logback.rollingpolicy.max-file-size: 1KB
logging.logback.rollingpolicy.file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}}.%i

②yml配置:

复制代码
logging:
  logback:
    rollingpolicy:
      max-file-size: 1KB
      file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}}.%i

(3)

logging.logback.rollingpolicy.file-name-pattern:日志分割后的文件名格式

logging.logback.rollingpolicy.max-file-size:日志文件超过这个大小就自动分割

5.4配置日志格式

(1)目前日志打印的格式是默认的,打印日志的格式,也是支持可配置的,支持控制台和日志文件分别设置。

(2)

logging.pattern.console:控制台日志格式

logging.pattern.file:日志文件的日志格式

①properties配置:

logging.pattern.console='%d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L [%thread] %m%n'

②yml配置:

logging:

pattern:

console:'%d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L [%thread] %m%n'

file:'%d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L [%thread] %m%n'

(3)通常情况下我们使用默认的日志打印格式就足够了




6、简单化的日志输出

6.1添加lombok依赖

每次使用日志工厂创建日志对象时十分繁琐的,而且几乎每个类都需要添加一遍,lombok给我们提供了一种更简单的方式就是使用 @Slf4j 注解输出日志

6.2使用注解@Slf4j输出日志

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
public class LogController {
    @RequestMapping("/log")
    public void log(){
        log.info("-----要输出日志内容-----");
    }
}
相关推荐
长潇若雪11 分钟前
结构体(C 语言)
c语言·开发语言·经验分享·1024程序员节
feilieren13 分钟前
leetcode - 684. 冗余连接
java·开发语言·算法
Peter44721 分钟前
-bash: ./my_rename.sh: /bin/bash^M: bad interpreter: No such file or directory
开发语言·bash
The Future is mine24 分钟前
Java根据word模板导出数据
java·开发语言
ChinaDragonDreamer24 分钟前
HarmonyOS:@Watch装饰器:状态变量更改通知
开发语言·harmonyos·鸿蒙
一颗甜苞谷37 分钟前
开源一款前后端分离的企业级网站内容管理系统,支持站群管理、多平台静态化,多语言、全文检索的源码
java·开发语言·开源
星夜孤帆37 分钟前
Java面试题集锦
java·开发语言
论迹1 小时前
【Java】-- 接口
java·开发语言
DARLING Zero two♡1 小时前
关于我、重生到500年前凭借C语言改变世界科技vlog.12——深入理解指针(2)
c语言·开发语言·科技·1024程序员节
小麦黑客笔记1 小时前
2024年最新自学手册 -网络安全(黑客技术)
开发语言·网络·安全·web安全·网络安全