目录
[🎈门面模式(外观模式)](#🎈门面模式(外观模式))
🚩Spring日志的认识
日志对于我们来说并不陌生,我们在学习javaee之前我们通过打印sout来观察程序的错误地方在哪里,而现在在spring的学习中,我们经常根据控制台的日志来分析和定位问题。
随着项⽬的复杂度提升, 我们对⽇志的打印也有了更⾼的需求, ⽽不仅仅是定位排查问题. ⽐如需要记录⼀些⽤⼾的操作记录(⼀些审计公司会要求), 也可能需要使⽤⽇志来记录⽤⼾的⼀些喜好,把⽇志持久化, 后续进⾏数据分析等. 但是 System.out.print 不能很好的满⾜我们的需求, 我们就需要使⽤⼀些专⻔⽇志框架(专业的事情交给专业的⼈去做)。
🚩Spring日志的作用
- 1.定位和发现问题
- 2.系统监控
- 3.数据采集
- 4.日志审记
🚩观察日志
Spring Boot 项⽬在启动的时候默认就有⽇志输出,如下图所⽰:
Spring帮我们集成了日志框架,我们可以直接使用即可。
🚩使用日志
打印⽇志的步骤:
- • 在程序中得到⽇志对象.
- • 使⽤⽇志对象输出要打印的内容
🎈在程序中得到日志对象
在程序中获取⽇志对象需要使⽤ ⽇志⼯⼚ LoggerFactory ,如下代码所⽰:
@RestController
public class LogsController {
private Logger logger= LoggerFactory.getLogger(LogsController.class);
}
LoggerFactory.getLogger 需要传递⼀个参数, 标识这个⽇志的名称. 这样可以更清晰的知道是哪个类输出的⽇志. 当有问题时, 可以更⽅便直观的定位到问题类(可以像上述观察日志的时候样子一样,可以知道打印日志的类是哪个)
注意:Logger 对象是属于 org.slf4j 包下的, 不要导⼊错包.
🎈使⽤⽇志对象输出要打印的内容
LogsController类:
@PostConstruct 是 Java 中的一种注解,用于在依赖注入完成后执行初始化方法。它通常用于需要在依赖注入完成后进行一些初始化工作的场景。这个注解可以用在任何被管理的 bean(如 Spring 管理的 bean 或 Java EE 的 EJB 和 CDI bean)的方法上。
@RestController
public class LogsController {
private Logger logger= LoggerFactory.getLogger(LogsController.class);
@PostConstruct
public void print(){
logger.info("-----------打印日志内容--------------");
}
}
运行结果:
🚩日志框架的介绍
slf4j并不是一个真实的日志实现,而是日志门面具体实现是log4j/logback等......
🎈门面模式(外观模式)
所谓门面模式,也称为外观模式,提供一个统一的接口,用来访问子系统的一段接口,其主要特征是定义了一个高层接口,让子系统更容易使用。
举个例子:我们进家门,我是一个比较怕黑的女生,我一进家门都是需要开灯的,等我一进门我需要先打开客厅的灯,然后打开厨房的灯,然后打开卧室的灯,一步一步的打开灯,然是如果形象化的理解门面模式,那就是我一进家门只用一个开关就打开了所有的灯,因为这个开关连接着各个灯的,所以这个开关就是提供的一个统一的接口,然后通过这个接口来访问系统的一段接口,方便了我们,也让子系统更容易的使用,不用我跑到厨房然后跑到卧室去开灯了,大大提升了开发效率,也简短了代码量。
⻔⾯模式主要包含2种⻆⾊:
- 外观⻆⾊(Facade): 也称⻔⾯⻆⾊,系统对外的统⼀接⼝.
- ⼦系统⻆⾊(SubSystem): 可以同时有⼀个或多个 SubSystem. 每个 SubSytem 都不是⼀个单独的类, ⽽是⼀个类的集合. SubSystem 并不知道 Facade 的存在, 对于 SubSystem ⽽⾔, Facade 只是另⼀个 客⼾端⽽已(即 Facade 对 SubSystem 透明)
(⽐如去医院看病,可能要去挂号, ⻔诊, 化验, 取药, 让患者或患者家属觉得很复杂, 如果有提供接待⼈员, 只让接待⼈员来处理, 就很⽅便)
👩🏻💻门面模式的实现
场景: 回家, 我们会开各个屋的灯. 离开家时, 会关闭各个屋的灯 ,如果家⾥设置⼀个总开关, 来控制整个屋的灯就会很⽅便. 我们使⽤⻔⾯模式的实现。
门面角色(系统对外的统一接口)
@Controller
public class LightFacade {
@Autowired
private bedroomLightFracade bedroomLightFracade;
@Autowired
private LivingLightFacade livingLightFacade;
@Autowired
private kitchenLightFracade kitchenLightFracade;
public void LightOn(){
livingLightFacade.on();
kitchenLightFracade.on();
bedroomLightFracade.on();
}
public void LightOff(){
livingLightFacade.off();
kitchenLightFracade.off();
bedroomLightFracade.off();
}
}
接口实现开灯关灯的行为
每个子系统实行接口并完成开灯和关灯的操作
主逻辑(也就是客户端)客户端只用调用统一接口
客户端不用知道里面的其他类是什么,只需要通过调用统一接口中的方法,即可打开和关闭灯。
@Controller
public class FacadePatternDemo {
@Autowired
private LightFacade lightFacade;
public void light() {
lightFacade.LightOn();
lightFacade.LightOff();
}
}
主程序中进行获取对象,并调用print方法
@SpringBootApplication
public class IocDemoApplication {
public static void main(String[] args) {
ApplicationContext context=SpringApplication.run(IocDemoApplication.class);
LightFacade lightFacade=context.getBean(LightFacade.class);
FacadePatternDemo facadePatternDemo=(FacadePatternDemo) context.getBean("facadePatternDemo");
facadePatternDemo.light();
}
}
👩🏻💻门面模式的优点
⻔⾯模式的优点
- • 减少了系统的相互依赖. 实现了客⼾端与⼦系统的耦合关系, 这使得⼦系统的变化不会影响到调⽤它的客⼾端;
- • 提⾼了灵活性, 简化了客⼾端对⼦系统的使⽤难度, 客⼾端⽆需关⼼⼦系统的具体实现⽅式, ⽽只需要和⻔⾯对象交互即可.
- • 提⾼了安全性. 可以灵活设定访问权限, 不在⻔⾯对象中开通⽅法, 就⽆法访问
🚩日志级别
⽇志级别是开发⼈员⾃⼰设置的. 开发⼈员根据⾃⼰的理解来判断该信息的重要程度
类似公司管理, 通常由领导来判断什么样的事情需要汇报, 什么样的事情不需要汇报. 针对这些级别, Logger 对象分别提供了对应的⽅法, 来输出⽇志
@RestController
public class LogsController {
private Logger logger= LoggerFactory.getLogger(LogsController.class);
@PostConstruct
public void print(){
logger.info("-----------info--------------");
logger.error("----------error-------------------");
logger.debug("------------debug------------------");
logger.warn("----------------warn-----------------");
logger.trace("---------------trace-----------------");
}
}
spring默认日志级别 :info
⽇志的输出级别默认是 info级别, 所以只会打印⼤于等于此级别的⽇志, 也就是info, warn和error. trace和debug级别都低于info,可以忽略不记。
🚩⽇志配置
上述是⽇志的使⽤, ⽇志框架⽀持我们更灵活的输出⽇志, 包括内容, 格式等。
🎈配置⽇志级别
⽇志级别配置只需要在配置⽂件中设置 "logging.level"配置项 即可,如下所⽰:
我们主要在yml配置文件中配置即可。
我们可以对日志进行分目录打印:比如Spring的日志只打印info,项目日志打印debug级别
logging:
level:
root: info #spring日志打印info级别
com:
example.ioc_demo:
controller: debug #项目日志打印debug级别
🎈⽇志持久化
以上的⽇志都是输出在控制台上的, 然⽽在线上环境中, 我们需要把⽇志保存下来, 以便出现问题之后追溯问题. 把⽇志保存下来就叫持久化。
⽇志持久化有两种⽅式
- 1. 配置⽇志⽂件名
- 2. 配置⽇志的存储⽬录
如果没有加路径,默认是放在当前项目下
配置⽇志⽂件的路径和⽂件名:
后⾯可以跟绝对路径或者相对路径
运⾏结果显⽰, ⽇志内容保存在了对应的⽬录下logging: file: name: logger/springboot.log
配置⽇志⽂件的保存路径
logging: file: path: D:/temp
两种方式都存在(存在优先级)logging: file: name: logger2/springboot.log path: D:/temp.log
- name既可以设置路径,又可以设置名称
- path只能设置路径,默认名称:spring.log
- 如果两者同时存在,path就失效了,name的优先级要高于path
注意: logging.file.name 和 logging.file.path 两个都配置的情况下, 只⽣效其⼀, 以 logging.file.name 为准
🎈日志分割
如果我们的⽇志都放在⼀个⽂件中, 随着项⽬的运⾏, ⽇志⽂件会越来越⼤, 需要对⽇志⽂件进⾏分割.
当然, ⽇志框架也帮我们考虑到了这⼀点, 所以如果不进⾏配置, 就⾛⾃动配置
默认⽇志⽂件超过10M就进⾏分割
logging:
file:
name: logger2/springboot.log
logback:
rollingpolicy:
max-file-size: 1KB
file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}.%i
不是达到1KB就立刻进行分割的,以行来分割,不是以字符分割的。企业中,通常日志分割大小为200m或者500m或者xxx。
- ⽇志⽂件超过1KB就分割(设置1KB是为了更好展⽰. 企业开发通常设置为200M, 500M等, 此处没有明确标准)
- 分割后的⽇志⽂件名为:⽇志名.⽇期.索引
每次重启进程,那么就都会生成一个日志文件是1kb的,是按分割的1kb,不是按字符来分割的1kb.
🎈修改日志格式
⽬前 ⽇志打印的格式是默认的
日志配置文件修改(控制台日志,日志文件)
这也对应了下面我们所看见的默认格式。一一对应关系。
如果我们想要改一下控制台日志格式,我们需要配置。
- 1.%clr(表达式){颜⾊} 设置输⼊⽇志的颜⾊ ,⽀持颜⾊有以下⼏种:
• blue
• cyan
• faint
• green
• magenta
• red
• yellow
- %d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd'T'HH:mm:ss.SSSXXX}} ⽇期和时间--精确到毫秒 %d{} ⽇期
${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd'T'HH:mm:ss.SSSXXX} ⾮空表达式, 获取
系统属性 LOG_DATEFORMAT_PATTERN , 若属性 LOG_DATEFORMAT_PATTERN 不存在,则使 ⽤ -yyyy-MM-dd HH:mm:ss.SSSXXX 格式, 系统属性可以System.getProperty("LOG_DATEFORMAT_PATTERN") 获取
- %5p 显⽰⽇志级别ERROR,MARN,INFO,DEBUG,TRACE.
- %t 线程名. %c 类的全限定名. %M method. %L 为⾏号. %thread 线程名称. %m 或者 %msg 显⽰输出消息. %n 换⾏符
- %5 若字符⻓度⼩于5,则右边⽤空格填充. %-5 若字符⻓度⼩于5,则左边⽤空格填充. %.15 若 字符⻓度超过15,截去多余字符. %15.15 若字符⻓度⼩于15,则右边⽤空格填充. 若字符⻓度超 过15,截去多余字符
🎈更简单的⽇志输出
每次都使⽤ LoggerFactory.getLogger(xxx.class) 很繁琐, 且每个类都添加⼀遍, lombok给我们提供了⼀种更简单的⽅式.
- 1. 添加 lombok 框架⽀持
- 2. 使⽤ @slf4j 注解输出⽇志
❗添加 lombok 依赖
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>
❗输出⽇志
@Slf4j @RestController public class LogsController { public void log(){ log.info("-----------info--------------"); } }
lombok提供的 @Slf4j 会帮我们提供⼀个⽇志对象 log, 我们直接使⽤就可以。
- 在idea反编译的字节码中,我们就可以看到已经创建了logger对象,然后根据创建的对象调用info级别的日志。
- 在源代码中用@Slf4j来帮助我们提供一个日志对象log,然后直接使用该log对象
🚩总结
常见的 Application Properties (配置文件官网)
- ⽇志是程序中的重要组成部分,使⽤⽇志可以快速的发现和定位问题,Spring Boot 内容了⽇志框架,默认情况下使⽤的是 info ⽇志级别将⽇志输出到控制台的,我们可以通过 lombok 提供的 @Slf4j 注解和 log 对象快速的打印⾃定义⽇志.
- ⽇志包含 6 个级别, ⽇志级别越⾼,收到的⽇志信息也就越少,我们可以通过配置⽇志的保存名称或保存⽬录来将⽇志持久化.
政治面貌:中共预备党员