
打印日志
打印日志的步骤:
 • 在程序中得到日志对象.
 • 使用日志对象输出要打印的内容
在程序中得到日志对象
在程序中获取日志对象需要使用日志工厂LoggerFactory,代码如下:
package com.example.demo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LoggerController {
    private static Logger logger = LoggerFactory.getLogger(LoggerController.class);
}
 
LoggerFactory.getLogger需要传递一个参数,用于标识该日志的出处,这样就可以清晰的看出该日志是哪个类输出的日志,方便观察调试,定位问题
 这里需要注意的是:
 Logger和LoggerFactory这两个类是属于org.slf4j包下的
使用日志对象输出要打印的内容
日志对象的打印级别有很多种,这里先打印info级别的日志:
package com.example.demo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/logger")
public class LoggerController {
    private static Logger logger = LoggerFactory.getLogger(LoggerController.class);
    @RequestMapping("/printLogger")
    public String printLogger(){
        logger.info("我是info级别的日志");
        return "打印日志";
    }
}
 


门面模式
真假日志框架
前面我们创建日志对象,导入了slf4j的包,因此,我们需要对slf4j进行深入的学习,要了解slf4j,就得先了解门面模式
 门面模式提供了一个统一的接口,用于调用子系统中的一群子接口,并对子系统的接口提供了一套规范,标准,接口.所有SLF4J并不能独立使用,需要和具体的日志框架配合使用
 
slf4j就是这样一个门面系统,因为它本身并不是一个真正的日志实现,而只是一个抽象层,对真正的日志框架提供了规范.
 常见的真正的日志框架有log4j,logback等
存在即合理
既然有真正的日志框架,那么为什么需要门面模式的存在?
 在不引入门面模式的时候
 当一个项目已经试用了log4j,假如出现一种情况,需要把logback也引入进去,那么就会引出以下问题:
门面模式的优点
• 减少了系统的相互依赖.实现了客户端与子系统的耦合关系,这使得子系统的变化不会影响到调用它的客户端;
 • 提高了灵活性,简化了客户端对子系统的使用难度,客户端无需关心子系统的具体实现方式,而只需要和门面对象交互即可.
 • 提高了安全性.可以灵活设定访问权限,不在门面对象中开通方法,就无法访问
日志格式的说明
打印的日志分别代表什么呢?
 
 从上图可以看到,日志输出内容元素具体如下:
- 时间日期:精确到毫秒
 - 日志级别:ERROR,WARN,INFO,DEBUG或TRACE
 - 进程ID
 - 线程名
 - Logger名(通常使用源代码的类名)
 - 日志内容
 
日志级别
日志级别的分类
日志的级别从高到低依次为:FATAL、ERROR、WARN、INFO、DEBUG、TRACE
 • FATAL:致命信息,表示需要立即被处理的系统级错误.
 • ERROR:错误信息,级别较高的错误日志信息,但仍然不影响系统的继续运行.
 • WARN:警告信息,不影响使用,但需要注意的问题
 • INFO:普通信息,用于记录应用程序正常运行时的⼀些信息,例如系统启动完成、请求处理完成等.
 • DEBUG:调试信息,需要调试时候的关键信息打印.
 • TRACE:追踪信息,比DEBUG更细粒度的信息事件(除非有特殊用意,否则请使用DEBUG级别替代)
日志级别的使用
        logger.trace("================= trace ===============");
        logger.debug("================= debug ===============");
        logger.info("================= info ===============");
        logger.warn("================= warn ===============");
        logger.error("================= error ===============");
        return "打印不同日志";
 
SpringBoot默认的日志框架是Logback,Logback没有 FATAL 级别,它被映射到ERROR .
 出现fatal日志,表示服务已经出现了某种程度的不可用,需要需要系统管理员紧急介入处理.通常情况下,一个进程生命周期中应该最多只有一次FATAL记录.
 
 
 结果发现,只打印了info,warn和error级别的日志
 这与日志级别的配置有关,日志的输出级别默认是info级别,所以只会打印大于等于此级别的日志,也就是info,warn和error.
日志配置
properties配置:
logging.level.root: debug
 
yml配置:
logging:
  level:
    root: debug
 
重新运行,就可以得到下面结果
 
日志持久化
以上的日志都是输出在控制台上的,然而在线上环境中,我们需要把日志保存下来,以便出现问题之后追溯问题.把日志保存下来就叫持久化.
 日志持久化有两种方式:
 1.配置日志文件名
logging.file.name= logger.log
 
logging:
  file:
    name: logger.log
 
运行结果显示,日志内容保存在了对应的目录下
 
2.配置日志的存储目录
logging.file.path: D:/temp
 
logging:
  file:
    path: D:/temp
 
运行程序,日志就会被保存到设置的磁盘目录下,但是这种方式只能设置日志的路径,文件名固定为spring.log
 
 注意:
 logging.file.name 和 logging.file.path 两个都配置的情况下,只生效其⼀,以
 logging.file.name 为准
配置日志文件分割
如果我们的日志都放在⼀个文件中,随着项目的运行,日志文件会越来越大,需要对日志文件进行分割,当然,如果我们不对它进行配置,系统就会让它走默认配置,即超过10MB就进行分割
| 配置项 | 说明 | 默认值 | 
|---|---|---|
| logging.logback.rollingpolicy.file-name-pattern | ⽇志分割后的⽂件名格式 | ${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz | 
| logging.logback.rollingpolicy.max-file-size | 日志文件超过这个大小就自动分割 | 10MB | 
| Properties配置: | 
logging.logback.rollingpolicy.file-name-pattern=${LOG_FILE}.%d{yyyy-MM-dd}.%i
logging.logback.rollingpolicy.max-file-size=1KB
 
yml配置:
logging:
  logback:
	rollingpolicy:
	  max-file-size: 1KB
	  file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}.%i
 
运行项目,多打印一些日志,得到以下结果:
 
更简单的日志输出
- 添加lombok框架支持
 - 使用 @slf4j 注解输出日志
 
添加lombok依赖
        <dependency>
		<groupId>org.projectlombok</groupId>
		<artifactId>lombok</artifactId>
		<optional>true</optional>
		</dependency>
 
日志输出
lombok提供的 @Slf4j 会帮我们提供⼀个日志对象log,我们直接使用就可以
package com.example.demo;
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("/info")
    public void log(){
        log.info("info");
    }
}
 











