JAVAEE之Spring Boot日志

1. 日志概述

1.1 学习日志的原因

⽇志对我们来说并不陌生,

从JavaSE部分,

我们就在使用 System.out.print 来打印日志了.

通过打印日志来发现和定位问题, 或者根据日志来分析程序的运行过程.

在Spring的学习中, 也经常根据控制台的日志来分析和定位问题.

随着项⽬的复杂度提升, 我们对日志的打印也有了更高的需求, 而不仅仅是定位排查问题.

比如需要记录⼀些用户的操作记录(⼀些审计公司会要求), 也可能需要使用日志来记录用户的⼀些喜好,把日志持久化, 后续进行数据分析等.

但是 System.out.print 不能很好的满⾜我们的需求, 我们就需要使用⼀些专门日志框架(专业的事情交给专业的人去做)

1.2 日志的用途

通过前面的学习, 我们知道日志主要是为了发现问题, 分析问题, 定位问题的, 但除此之外, 日志还有很多用途
1. 系统监控
监控现在⼏乎是⼀个成熟系统的标配, 我们可以通过⽇志记录这个系统的运⾏状态, 每⼀个⽅法的响应时间, 响应状态等, 对数据进⾏分析, 设置不同的规则, 超过阈值时进⾏报警. ⽐如统计⽇志中关键字的数量,并在关键字数量达到⼀定条件时报警,这也是⽇志的常⻅需求之⼀、

2. 数据采集
数据采集是⼀个⽐较⼤的范围, 采集的数据可以作⽤在很多⽅⾯, ⽐如数据统计, 推荐排序等.
• 数据统计: 统计⻚⾯的浏览量(PV), 访客量(UV), 点击量等, 根据这些数据进⾏数据分析, 优化公司运营策略
• 推荐排序: 目前推荐排序应用在各个领域, 我们经常接触的各⾏各业很多也都涉及推荐排序, ⽐如购物, 广告, 新闻等领域. 数据采集是推荐排序⼯作中必须做的⼀环, 系统通过⽇志记录⽤⼾的浏览历史, 停留时⻓等, 算法⼈员通过分析这些数据, 训练模型, 给⽤⼾做推荐.

3. ⽇志审计
随着互联⽹的发展,众多企业的关键业务越来越多的运⾏于⽹络之上. ⽹络安全越来越受到⼤家的关注, 系统安全也成为了项⽬中的⼀个重要环节, 安全审计也是系统中⾮常重要的部分. 国家的政策法规、⾏业标准等都明确对⽇志审计提出了要求. 通过系统⽇志分析,可以判断⼀些⾮法攻击, ⾮法调⽤,以及系统处理过程中的安全隐患. 

2. ⽇志使⽤

Spring Boot 项⽬在启动的时候默认就有⽇志输出,如下图所⽰: 

我们知道,通过 System.out.print 打印的⽇志, ⽐ SpringBoot 打印的⽇志缺少了很多信息
SpringBoot 内置了⽇志框架 Slf4j , 我们可以直接在程序中调⽤ Slf4j 来输出⽇志

2.1 打印⽇志

打印⽇志的步骤:
• 在程序中得到日志对象.
• 使⽤日志对象输出要打印的内容 

2.1.1 在程序中得到⽇志对象

在程序中获取⽇志对象需要使用日志工厂 LoggerFactory,如下代码所⽰:

private static Logger longer= LoggerFactory.getILoggerFactory(LoggerController.class);

LoggerFactory.getLogger 需要传递⼀个参数, 标识这个⽇志的名称. 这样可以更清晰的知道是哪个类输出的⽇志. 当有问题时, 可以更⽅便直观的定位到问题类

注意:Logger对象是属于org.slf4j包下的,不要导错包。

2.1.2 使⽤⽇志对象打印⽇志

⽇志对象的打印⽅法有很多种,我们可以先使⽤ 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
public class LoggerController {private static Logger logger= LoggerFactory.getLogger(LoggerController.class);@RequestMapping("/logger")public String logger(){logger.info("------要输出的日志内容------");System.out.println("打印⽇志");return "打印⽇志";}
}

 浏览器输入:127.0.0.1:8080/logger查看效果

 2.2 ⽇志框架介绍(了解)

SLF4J不同于其他⽇志框架, 它不是⼀个真正的⽇志实现, ⽽是⼀个抽象层, 对⽇志框架制定的⼀种规范,标准, 接⼝. 所有SLF4J并不能独⽴使⽤, 需要和具体的⽇志框架配合使⽤。

2.2.1 ⻔⾯模式(外观模式)

SLF4J是⻔⾯模式的典型应⽤(但不仅仅使⽤了⻔⾯模式).
⻔⾯模式定义
⻔⾯模式(Facade Pattern)⼜称为外观模式, 提供了⼀个统⼀的接⼝, ⽤来访问⼦系统中的⼀群接⼝.
其主要特征是定义了⼀个⾼层接⼝, 让⼦系统更容易使⽤。

⻔⾯模式主要包含2种⻆⾊:
外观⻆⾊(Facade): 也称⻔⾯⻆⾊,系统对外的统⼀接⼝.
⼦系统⻆⾊(SubSystem): 可以同时有⼀个或多个 SubSystem. 每个 SubSytem 都不是⼀个单独的类,
⽽是⼀个类的集合. SubSystem 并不知道 Facade 的存在, 对于 SubSystem ⽽⾔, Facade 只是另⼀个客⼾端⽽已(即 Facade 对 SubSystem 透明)

2.2.1.2 ⻔⾯模式的优点
减少了系统的相互依赖. 实现了客⼾端与⼦系统的耦合关系, 这使得⼦系统的变化不会影响到调⽤它的客⼾端;
提⾼了灵活性, 简化了客⼾端对⼦系统的使⽤难度, 客⼾端⽆需关⼼⼦系统的具体实现⽅式, ⽽只需要和⻔⾯对象交互即可.
提⾼了安全性. 可以灵活设定访问权限, 不在⻔⾯对象中开通⽅法, 就⽆法访问

 

2.2.2 SLF4J 框架介绍

SLF4J 就是其他⽇志框架的⻔⾯.
SLF4J 可以理解为是提供⽇志服务的统⼀API接⼝, 并不涉及到具体的⽇志逻辑实现.
2.2.2.1 不引⼊⽇志⻔⾯
常⻅的⽇志框架有log4J, logback等. 如果⼀个项⽬已经使⽤了log4j,⽽你依赖的另⼀个类库,假如是Apache Active MQ, 它依赖于另外⼀个⽇志框架logback, 那么你就需要把logback也加载进去.

 存在问题:
1. 不同⽇志框架的API接⼝和配置⽂件不同, 如果多个⽇志框架共存, 那么不得不维护多套配置⽂件(这个配置⽂件是指⽤⼾⾃定义的配置⽂件).
2. 如果要更换⽇志框架, 应⽤程序将不得不修改代码, 并且修改过程中可能会存在⼀些代码冲突.
3. 如果引⼊的第三⽅框架, 使⽤了多套, 那就不得不维护多套配置

2.2.2.2 引⼊⽇志⻔⾯

引⼊⻔⾯⽇志框架之后, 应⽤程序和⽇志框架(框架的具体实现)之间有了统⼀的API接⼝(⻔⾯⽇志框架实现), 此时应⽤程序只需要维护⼀套⽇志⽂件配置, 且当底层实现框架改变时, 也不需要更改应⽤程序代码 

 

SLF4J 就是这个⽇志⻔⾯.
总的来说,SLF4J使你的代码独⽴于任意⼀个特定的⽇志API,这是⼀个对于开发API的开发者很好的思想.

2.3 ⽇志格式的说明

打印的⽇志分别代表什么呢?

 

从上图可以看到,⽇志输出内容元素具体如下:
1. 时间⽇期:精确到毫秒
2. ⽇志级别:ERROR, WARN, INFO, DEBUG 或TRACE
3. 进程ID
4. 线程名
5. Logger名(通常使⽤源代码的类名)
6. ⽇志内容

2.4 ⽇志级别

⽇志级别代表着⽇志信息对应问题的严重性, 为了更快的筛选符合⽬标的⽇志信息

 -有了⽇志级别之后就可以过滤⾃⼰想看到的信息了,

⽐如只关注error级别的, 就可以根据级别过滤出来error级别的⽇志信息, 节约开发者的信息筛选时间

2.4.1 ⽇志级别的分类

⽇志的级别从⾼到低依次为: FATAL、ERROR、WARN、INFO、DEBUG、TRACE
FATAL: 致命信息,表⽰需要⽴即被处理的系统级错误.
ERROR: 错误信息, 级别较⾼的错误⽇志信息, 但仍然不影响系统的继续运⾏.
WARN: 警告信息, 不影响使⽤, 但需要注意的问题
INFO: 普通信息, ⽤于记录应⽤程序正常运⾏时的⼀些信息, 例如系统启动完成、请求处理完成等.
DEBUG: 调试信息, 需要调试时候的关键信息打印.
TRACE: 追踪信息, ⽐DEBUG更细粒度的信息事件(除⾮有特殊⽤意,否则请使⽤DEBUG级别替代)
⽇志级别通常和测试⼈员的Bug级别没有关系.
⽇志级别是开发⼈员设置的, ⽤来给开发⼈员看的. ⽇志级别的正确设置, 也与开发⼈员的⼯作经验有关.
如果开发⼈员把error级别的⽇志设置成了info, 就很有可能会影响开发⼈员对项⽬运⾏情况的判断. 出现error级别的⽇志信息较多时, 可能也没有任何问题. 测试的bug级别更多是依据现象和影响范围来判断

⽇志级别的顺序:

 

级别越⾼, 收到的消息越少

2.4.2 ⽇志级别的使⽤

⽇志级别是开发⼈员⾃⼰设置的. 开发⼈员根据⾃⼰的理解来判断该信息的重要程度
类似公司管理, 通常由领导来判断什么样的事情需要汇报, 什么样的事情不需要汇报.
针对这些级别, Logger 对象分别提供了对应的⽅法, 来输出⽇志
/*** 打印不同级别的⽇志* @return*/
@RequestMapping("/printLog")
public String printLog() {logger.trace("================= trace ===============");logger.debug("================= debug ===============");logger.info("================= info ===============");logger.warn("================= warn ===============");logger.error("================= error ===============");return "打印不同级别的⽇志" ;
}
127.0.0.1:8080/printLog
SpringBoot 默认的⽇志框架是Logback, Logback没有 FATAL 级别, 它被映射到 ERROR .
出现fatal⽇志,表⽰服务已经出现了某种程度的不可⽤, 需要需要系统管理员紧急介⼊处理. 通常情况下, ⼀个进程⽣命周期中应该最多只有⼀次FATAL记录.

 

结果发现, 只打印了info, warn和error级别的⽇志
这与⽇志级别的配置有关, ⽇志的输出级别默认是 info级别, 所以只会打印⼤于等于此级别的⽇志, 也就是info, warn和error.

2.5 ⽇志配置

上述是⽇志的使⽤, ⽇志框架⽀持我们更灵活的输出⽇志, 包括内容, 格式等.

2.5.1 配置⽇志级别

⽇志级别配置只需要在配置⽂件中设置"logging.level"配置项即可,如下所示
logging.level.root: debug
重新运⾏上述代码, 观察结果:

 

2.5.2 ⽇志持久化

以上的⽇志都是输出在控制台上的, 然⽽在线上环境中, 我们需要把⽇志保存下来, 以便出现问题之后追溯问题.
把⽇志保存下来就叫持久化.
⽇志持久化有两种⽅式
1. 配置⽇志⽂件名
logging.file.name : logger/springboot.log
后⾯可以跟绝对路径或者相对路径
2. 配置⽇志的存储⽬录
logging.file.path : D:/temp
这种⽅式只能设置⽇志的路径, ⽂件名为固定的spring.log
注意:
logging.file.name logging.file.path 两个都配置的情况下,
只⽣效其⼀,
logging.file.name 为准 

2.5.3 配置⽇志⽂件分割

如果我们的⽇志都放在⼀个⽂件中, 随着项⽬的运⾏, ⽇志⽂件会越来越⼤, 需要对⽇志⽂件进⾏分割.
当然, ⽇志框架也帮我们考虑到了这⼀点, 所以如果不进⾏配置, 就⾛⾃动配置
默认⽇志⽂件超过10M就进⾏分割
配置项说明默认值
logging.logback.rollingpolicy.fil
e-name-pattern
⽇志分割后的⽂件名
格式
${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz
logging.logback.rollingpolicy.m
ax-file-size
⽇志⽂件超过这个⼤
⼩就⾃动分割
10MB

配置日志文件分割

logging.logback.rollingpolicy.file-name-pattern = ${LOG_FILE}.%d{yyyy-MM-dd}.%i
logging.logback.rollingpolicy.max-file-size = 1KB
1. ⽇志⽂件超过1KB就分割(设置1KB是为了更好展⽰. 企业开发通常设置为200M, 500M等, 此处没
有明确标准)
2. 分割后的⽇志⽂件名为: ⽇志名.⽇期.索引

项⽬运⾏, 多打印⼀些⽇志, ⽇志分割结果:

 

2.5.4 配置⽇志格式

⽬前⽇志打印的格式是默认

打印⽇志的格式, 也是⽀持配置的. ⽀持控制台和⽇志⽂件分别设置(不重要)

3. 更简单的⽇志输出

每次都使⽤ LoggerFactory.getLogger(xxx.class) 很繁琐, 且每个类都添加⼀遍, lombok给我们提供了
⼀种更简单的⽅式.
1. 添加 lombok 框架⽀持
2. 使⽤ @slf4j 注解输出⽇志(注解类class)
lombok提供的 @Slf4j 会帮我们提供⼀个⽇志对象 log, 我们直接使⽤就可以

4. 总结

1. ⽇志是程序中的重要组成部分,使⽤⽇志可以快速的发现和定位问题,Spring Boot 内容了⽇志框架,默认情况下使⽤的是 info ⽇志级别将⽇志输出到控制台的,我们可以通过 lombok 提供的@Slf4j 注解和 log 对象快速的打印⾃定义⽇志.
2. ⽇志包含 6 个级别, ⽇志级别越⾼,收到的⽇志信息也就越少,我们可以通过配置⽇志的保存名称或保存⽬录来将⽇志持久化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/299266.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【图论】【分类讨论】LeetCode3017按距离统计房屋对数目

本文涉及的知识点 图论 分类讨论 本题同解 【差分数组】【图论】【分类讨论】【整除以2】3017按距离统计房屋对数目 LeetCode3017按距离统计房屋对数目 给你三个 正整数 n 、x 和 y 。 在城市中,存在编号从 1 到 n 的房屋,由 n 条街道相连。对所有 …

Python 基于列表实现的通讯录管理系统(有完整源码)

目录 通讯录管理系统 PersonInformation类 ContactList类 menu函数 main函数 程序的运行流程 完整代码 运行示例 通讯录管理系统 这是一个基于文本的界面程序,用户可以通过命令行与之交互,它使用了CSV文件来存储和读取联系人信息,这…

Docker实战教程 第1章 Linux快速入门

2-1 Linux介绍 为什么要学Linux 三个不得不学习 课程需要:Docker开发最好在Linux环境下。 开发需要:作为一个后端程序员,是必须要掌握Linux的,这是找工作的基础门槛。 运维需要:在服务器端,主流的大型服…

Java栈和队列的实现

目录 一.栈(Stack) 1.1栈的概念 1.2栈的实现及模拟 二.队列(Queue) 2.1队列的概念 2.2队列的实现及模拟 2.3循环队列 2.4双端队列(Deque) 一.栈(Stack) 1.1栈的概念 栈:一种特殊的线性表,其 只允许在固定的一端进行插入和删除元素操作…

element-ui result 组件源码分享

今日简单分享 result 组件的源码实现,主要从以下三个方面: 1、result 组件页面结构 2、result 组件属性 3、result 组件 slot 一、result 组件页面结构 二、result 组件属性 2.1 title 属性,标题,类型 string,无默…

11-1(2)-CSS 背景+CSS 精灵图

个人主页:学习前端的小z 个人专栏:HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结,欢迎大家在评论区交流讨论! 文章目录 一、CSS 背景1 背景颜色2 背景色半透明3 背景图片4 背景平铺5 背景图片位置6 …

linux操作系统安装及命令初识,上岸蚂蚁金服

310 包) desktop 1800个包左右 内容必须大于 768M 系统设置 分区设置 挂载点 /boot / swap 交换分区–占用磁盘容量 网络配置 网卡配置 设置为ON 主机名配置 Begin installation 设置 root 用户密码 命令初识 命令 选项 参数: 命令选项参数…

JavaEE 初阶篇-生产者与消费者模型(线程通信)

🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 生产者与消费者模型概述 2.0 在生产者与消费者模型中涉及的关键概念 2.1 缓冲区 2.2 生产者 2.3 消费者 2.4 同步机制 2.5 线程间通信 3.0 实现生产者与消费者模…

iOS开发进阶(十三):脚手架创建iOS项目

文章目录 一、前言二、xcode-select 命令三、拓展阅读 一、前言 项目初期,需要搭建项目基本框架,为此离不开辅助工具,即脚手架。当然,IDE也可以实现新建空白项目,但是其新建后的项目结构可能不符合预期设计&#xff0…

AWS-EKS 给其他IAM赋予集群管理权限

AWS EKS 设计了权限管理系统,A用户创建的集群 B用户是看不到并且不能管理和使用kubectl的,所以我们需要共同管理集群时就需要操场共享集群访问给其他IAM用户。 两种方式添加集群控制权限(前提:使用有管理权限的用户操作&#xff…

顺序表相关习题

🌈 个人主页:白子寰 🔥 分类专栏:python从入门到精通,魔法指针,进阶C,C语言,C语言题集,C语言实现游戏👈 希望得到您的订阅和支持~ 💡 坚持创作博文…

Java笔试题总结

HashSet子类依靠()方法区分重复元素。 A toString(),equals() B clone(),equals() C hashCode(),equals() D getClass(),clone() 答案:C 解析: 先调用对象的hashcode方法将对象映射为数组下标,再通过equals来判断元素内容是否相同 以下程序执行的结果是: class X{…

【项目实战经验】DataKit迁移MySQL到openGauss(上)

前言 本文将分享DataKit迁移MySQL到openGauss的项目实战,供广大openGauss爱好者参考。 1. 下载操作系统 https://www.openeuler.org/zh/download https://support.huawei.com/enterprise/zh/doc/EDOC1100332931/1a643956 https://support.huawei.com/enterprise…

CSS基础选择器 小案例复习(画三个小盒子)

(大家好,前面我们学习了基础的选择器,俗话说:温故而知新。所以今天我们将通过小案例来复习前面学过的小知识点。另,十分感谢大家对我文章的支持❤️) 通过这个案例复习两个地方: 类选择器的使用…

基于ZooKeeper的Kafka分布式集群搭建与集群启动停止Shell脚本

下载Kafka压缩包 下方是Kafka官网下载地址,本文使用Kafka 3.0.0在虚拟机环境中搭建分布式集群。 Apache Kafka Downloads link 虽然在Kafka 2.8.0之后可以使用KRaft模式搭建高可用的集群以提高数据处理效率,但是目前还有许多企业依然使用ZooKeeper搭建K…

uni-app如何实现高性能

这篇文章主要讲解uni-app如何实现高性能的问题? 什么是uni-app? 简单说一下什么是uni-app,uni-app是继承自vue.js,对vue做了轻度定制,并且实现了完整的组件化开发,并且支持多端发布的一种架构&#xff0c…

申请SSL证书

有很多方法可以确保您的网站安全。添加SSL证书可针对恶意攻击提供额外且关键的保护层。 即使网站不接受交易,您仍然需要保护用户的登录详细信息、地址和其他个人信息。 没有SSL证书的网站使用HTTP(一种基于文本的协议),这意味着…

红队攻防之PowerShell基础免杀(二)

Get busy living or get busy dying 什么是图片免杀? 答:一般情况下,某些 AV 对图像未执行检测处理。这种情况下,它们可以仅使用有效负载数据来生成新图像,或将有效负载嵌入到现有图像的最低有效字节中,使…

泰坦尼克号幸存者数据分析

泰坦尼克号幸存者数据分析 1、泰坦尼克号数据集2、数据集加载与概览3、泰坦尼克号幸存者数据分析4、哪些人可能成为幸存者? 1、泰坦尼克号数据集 泰坦尼克号的沉没是世界上最严重的海难事故之一,造成了大量的人员伤亡。这是一艘号称当时世界上最大的邮轮…

linux基础8:文件系统

linux基础8:文件系统 1.物理存储->逻辑存储:1.从磁盘到分区:1.基本物理结构2.物理存储结构3.逻辑结构4.操作系统的Io需求:5.分区操作and分组操作: 2.文件系统结构:1.基本结构:2.分组区块&…