🌸个人主页:https://blog.csdn.net/2301_80050796?spm=1000.2115.3001.5343
🏵️热门专栏:
🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm=1001.2014.3001.5482
🍕 Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm=1001.2014.3001.5482
🧀线程与网络(96平均质量分) https://blog.csdn.net/2301_80050796/category_12643370.html?spm=1001.2014.3001.5482
🍭MySql数据库(93平均质量分)https://blog.csdn.net/2301_80050796/category_12629890.html?spm=1001.2014.3001.5482
🍬算法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12676091.html?spm=1001.2014.3001.5482
🍃 Spring(97平均质量分)https://blog.csdn.net/2301_80050796/category_12724152.html?spm=1001.2014.3001.5482
感谢点赞与关注~~~
目录
- [1. 日志的使用](#1. 日志的使用)
-
- [1.1 打印日志](#1.1 打印日志)
- [1.2 日志框架](#1.2 日志框架)
-
- [1.2.1 门面模式(外观模式)](#1.2.1 门面模式(外观模式))
- [1.2.2 slf4j框架介绍](#1.2.2 slf4j框架介绍)
- [1.3 日志格式说明](#1.3 日志格式说明)
- [1.4 日志级别](#1.4 日志级别)
-
- [1.4.1 日志级别的分类](#1.4.1 日志级别的分类)
- [1.4.2 日志级别的使用](#1.4.2 日志级别的使用)
- [1.5 日志配置](#1.5 日志配置)
-
- [1.5.1 配置日志级别](#1.5.1 配置日志级别)
- [1.5.2 日志持久化(把日志存储在硬盘中)](#1.5.2 日志持久化(把日志存储在硬盘中))
- [1.5.3 配置日志文件的分割](#1.5.3 配置日志文件的分割)
- [2. 更简单的日志输出](#2. 更简单的日志输出)
1. 日志的使用
在SpringBoot项目启动的时候,就会默认有日志输出.
如果我们使用sout去打印日志,那么日志就不会像Spring默认的这样打印出来,只会打印规定输出的内容,相比这些缺少了很多的信息.
我们为了打印出信息更加齐全的日志,Spring内置了日志的框架,叫做Slf4j
,我们可以直接在程序中调用Slf4j 来输出日志.
1.1 打印日志
打印日志有以下两个步骤:
- 在程序中获取到日志对象.
在程序中获取日志对象的时候,我们需要使用到一个工厂类,叫做LoggerFactory
,我们称它为日志工厂.代码如下:
java
package com.jrj.logger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LoggerDemo {
public static Logger logger = LoggerFactory.getLogger(LoggerDemo.class);
}
需要注意的是,在输入Logger这个类之后,编译器会有很多的提示,一定要选择slf4j这个包下的一个接口,不要选错了.还有,工厂类后面方法中的参数传入的是一个类对象,这个括号中传入的是哪个类的类对象,就表示哪个类在打印日志.
- 使用日志对象输出要打印的内容.
使用日志对象打印的方式有好多种.我们先通过logger对象调用info方法来输出日志:
java
@RestController
public class LoggerDemo {
public static Logger logger = LoggerFactory.getLogger(LoggerDemo.class);
@PostConstruct
public static String printLogger(){
logger.info("打印日志");
return "打印日志";
}
}
运行结果:
1.2 日志框架
日志其实并不是由slf4j自己实现的,它只是⼀个抽象层,对日志框架制定的⼀种规范,标准,接口.真正实现日志的其实是底层的logback,所以slf4j不可以单独使用,需要搭配具体的日志框架来使用.
1.2.1 门面模式(外观模式)
在slf4j中使用了一种典型的设计模式,叫做门面模式.
门面模式又称为外观模式,提供了⼀个统⼀的接口,用来访问子系统中的⼀群接口.其主要特征是定义了⼀个高层接口,让子系统更容易使用.
- 门面模式中主要包含两种角色
- 门面角色,是系统对外提供的统一的接口,也叫外观角色.
- 子系统角色,可以同时有⼀个或多个SubSystem,每个SubSytem都不是⼀个单独的类,而是⼀个类的集合.
举例说明:去医院看病
病人去医院看病,可能要去挂号,就诊,化验,取药等一系列繁杂的操作,让患者和家属觉得很麻烦,这事如果医院有一个接待人员,就会方便很多.
- 实现门面模式
场景:家里的灯,各个屋子都有各自的开关,可以控制各个屋子的灯,在门口的地方有一个总开关,可以控制所有的灯.一关全关.
java
public interface ILight {
void on();//开灯接口
void off();//关灯接口
}
public class LivingroomLight implements ILight{
@Override
public void on() {
System.out.println("打开客厅灯");
}
@Override
public void off() {
System.out.println("关闭客厅灯");
}
}
public class BedroomLight implements ILight{
@Override
public void on() {
System.out.println("打开卧室灯");
}
@Override
public void off() {
System.out.println("关闭卧室灯");
}
}
public class FacadeLight implements ILight{
public LivingroomLight livingroomLight = new LivingroomLight();
public BedroomLight bedroomLight = new BedroomLight();
@Override
public void on() {
livingroomLight.on();
bedroomLight.on();
}
@Override
public void off() {
livingroomLight.off();
bedroomLight.off();
}
}
运行结果:
1.2.2 slf4j框架介绍
SLF4J就是其他日志框架的门面.SLF4J可以理解为是提供日志服务的统⼀API接口,并不涉及到具体的日志逻辑实现.
- 不引入日志门面
假如一个项目你已经依赖了log4j日志框架,假如你依赖的另一个类库假如是Apache Active MQ,它依赖的日志框架是logback日志框架,那么你需要把logback也导入进去.
存在的问题:
- 不同日志框架的API接口和配置文件不同,如果多个日志框架共存,那么不得不维护多套配置文件(这个配置文件是指用户自定义的配置文件).
- 如果要更换日志框架,应用程序将不得不修改代码,并且修改过程中可能会存在⼀些代码冲突.
- 如果引入的第三方框架,使用了多套,那就不得不维护多套配置.
- 引入日志门面
应用程序和日志框架(框架的具体实现)之间有了统⼀的API接口(门面日志框架实现),此时应用程序只需要维护⼀套日志文件配置,且当底层实现框架改变时,也不需要更改应用程序代码.
其中我们的slf4j就是一个日志门面,它会把底层的日志框架统一起来,之后使用统一的接口来提供给用户.使你的代码独立于任何一个特定的日志框架API.
1.3 日志格式说明
- 日志打印时间,可以精确到毫秒.
- 日志级别,分为ERROR,WARN,INFO,DEBUG或TRACE
- 进程ID
- 打印日志的项目(项目名称取决于配置文件)
- 线程名称.
- Logger名
- 日志内容.
1.4 日志级别
1.4.1 日志级别的分类
日志级别代表着日志信息对应问题的严重性,为了更快的筛选符合目标的日志信息.
日志的级别从高到低依次为:FATAL、ERROR、WARN、INFO、DEBUG、TRACE.
• FATAL:致命信息,表示需要立即被处理的系统级错误.
• ERROR:错误信息,级别较高的错误日志信息,但仍然不影响系统的继续运行.
• WARN:警告信息,不影响使用,但需要注意的问题
• INFO:普通信息,用于记录应用程序正常运行时的⼀些信息,例如系统启动完成、请求处理完成等.
• DEBUG:调试信息,需要调试时候的关键信息打印.
• TRACE:追踪信息,比DEBUG更细粒度的信息事件(除非有特殊用意,否则请使用DEBUG级别替代)
级别顺序:
fatal级别的日志,表示服务器出现了某种程度上的不可用,需要程序员紧急介入处理,一般在一个程序的生命周期中fatal级别的日志只会出现一次.
1.4.2 日志级别的使用
打印日志的级别,可由开发人员根据信息的重要程度和自己的理解自己设置日志级别.针对这些不同的日志级别,Logger对象也提供了不同的方法来打印不同级别的日志.
java
@RestController
public class LoggerDemo {
public static Logger logger = LoggerFactory.getLogger(LoggerDemo.class);
@PostConstruct
public static String printLogger(){
logger.info("打印info日志");
logger.error("打印error日志");
logger.warn("打印warn日志");
logger.debug("打印debug日志");
logger.trace("打印trace日志");
return "打印日志";
}
}
在这几个日志级别中,默认fatal(被映射到了error级别),debug,trace这几个级别的日志不会输出.但是可以通过配置文件修改起始打印级别.
1.5 日志配置
上述是日志的使用,日志框架支持我们更灵活的输出日志,包括内容,格式等.
1.5.1 配置日志级别
日志级别配置只需要在配置文件中设置"logging.level"配置项即可,如下:(以yml文件格式为例)
yml
logging:
level:
root: debug
我们看到,debug级别的日志也被打印了出来.
这里其中的root表示的是该项目下的所有文件的日志,我们也可以通过在level下面加上软件包的树形结构来限定只有规定包下文件的日志从指定级别开始打印.
yml
logging:
level:
com:
jrj:
logger: trace
我们看到只有我们刚刚自己写的日志被打印了出来,没有像上面打印的那么多的信息.
1.5.2 日志持久化(把日志存储在硬盘中)
我们之前的日志都是在控制台上打印日志,这就意味着日志在内存中,如何在硬盘中永久存储日志呢?
日志持久化有两种方式:
- 配置日志文件的文件名,文件名中既可以设置路径,又可以设置文件名.
yml
logging:
level:
com:
jrj:
logger: trace
file:
name: logger/springLogger.log
file下面的几行就是在使用文件名配置日志文件.
我们看到在项目的目录之下,多出了一个logger的目录,目录中就存储的是指定路径之下 的日志.
[注意]
- 日志在log文件中存储的时候是以追加的形式存储的,当我们再次运行项目的时候,如果不改变配置文件中的文件名,新的日志就会追加在下面.
- 配置文件中如果是同一个配置项在配置文件中不可以出现两次或以上,需要把他们合并到一起.
- 配置日志文件的存储路径,可以是相对路径,可以是绝对路径.路径中只可以设置路径.
yml
logging:
level:
com:
jrj:
logger: trace
file:
path: D:/personal
我们看到日志文件被保存在了指定的路径之下.
[注意] 如果name和path两个配置项同时存在的时候,优先使用name配置项.
1.5.3 配置日志文件的分割
如果日志一直不停地产生的话,日志文件就会越来越大.此时需要对项目的日志进行分割.当然,日志框架也考虑到了这一点,没有配置参数的默认情况下,一个日志文件满10M就会自动进行分割.
- 配置项
yml
logging:
file:
path: D:/personal
logback:
rollingpolicy:
file-name-pattern: ${spring_log}.%d{yyyy-MM-dd}.%i.gz
max-file-size: 2KB
上面的参数分别表示的是,分割后文件的名字,格式就是文件名+日期+索引+文件格式,以及一个日志文件的最大大小.
2. 更简单的日志输出
每次都使用LoggerFactory很繁琐,每个类都要添加一遍Logger对象,于是lombok就为我们提供了一种特别方便的方式.
- 添加lombok依赖
- 使用
@Slf4j
注解产生Logger对象,使用注解产生的对象进行日志输出.产生的这个对象默认的名字是log.注意注解中的首字母是大写的.
java
@RestController
@Slf4j
public class LoggerDemo {
@PostConstruct
public static String printLogger(){
log.info("打印info日志");
log.error("打印error日志");
log.warn("打印warn日志");
log.debug("打印debug日志");
log.trace("打印trace日志");
return "打印日志";
}
}
运行结果:
同样可以打印自定义的日志.