SpringBoot日志文件
日志有什么用?
1)快速的排查和定位问题,直接看报错信息;
2)进行记录用户登录的信息记录业务功能日志方便分析用户是正常登录还是暴力破解用户;
假设我们在这个登录程序中没有写反暴力破解的机制,比如说用户输入密码六次之后锁定三分钟,输入10次之后锁定10分钟,假设用户在极短的时间内连续输入多次密码,我们就可以进行记录下来,可以是不是看一下日志,从而分析用户的行为,从而给你的系统提供一个更加安全稳定的工作环境了,发现用户不正常的行为,发现一天一个人登录10W次,我们查看登录日志,发现登录日志暴增,正常情况下登录日志2000条,但是有一天发现暴增10000条,我们就可以设置黑名单,发现是暴力破解;
3)记录系统的操作日志帮助恢复数据和定位责任人
误删数据之后之前记录删除日志的信息和时间,人工进行恢复,日志已经记录了操作之前的数据和操作之后的数据,非常重要的流程以及操作频率比较低的记录操作记录下来;
某个人不小心把信息删除了,想推拖责任,就可以通过日志找到操作人;
4)记录每一个方法的执行时间
方便后期的优化和分析,某一个模块方法的执行时间,最后把所有模块执行时间列出来,看看那个模块执行时间长,可以定位到类和方法,从而做出针对性性能优化,可以通过AOP拦截,我们可以针对每一个方法的执行时间进行排序,比如说前五条进行优化;
5)还有一个具体的应用:比如说教务系统有两个功能,写作业功能和查看论坛功能,咱们的写作业功能使用Java代码写的,但是咱们的查看论坛功能使用PHP写的,所以说当用户进行注册教务系统的时候,当我们给作业系统添加一条用户注册,同时也会在论坛里面同一时间添加一条相同的用户记录;这样的目的就是实现一次注册,同时在两个系统注册,相当于在程序中使用极低的成本来实现用户数据的同步
5.1)假设现在有一个新的系统注册教务系统,先给用户写作业系统添加一条记录,但是此时插入查看论坛系统失败了,系统就会一直死等,空转CPU资源,第二步注册一直过不去,这是客户端就会看到服务器繁忙,用户体验就会非常不好,(因为当我们进行注册作业教务系统的时候,会注册一条相同的记录给论坛系统);
5.2)这是该怎们进行解决呢?我们设置无论论坛是否注册成功,都会给用户返回成功,如果论坛真的注册失败了,设置超时时间,超过论坛注册超时时间,我们就记录一下日志,进行报警,等待论坛恢复正常了之后,把日志给后台的管理人员,让管理员手动把用户注册作业功能成功,但是论坛失败的用户手动插入同步到查看论坛系统,手动进行数据补偿,这样就最低成本的解决了问题;
1)SpringBoot中内置了日志框架,像是SprinBoot内置了测试框架,Jackon;
2)默认情况下,输出的日志并不是开发者进行定义和打印的,而是由系统打印的,我们是不2.1)可以直接使用System.out.println来进行打印的,但是系统正常的日志有时间点的,发生时间,日志级别,哪个类里面,关键信息都很全;
2.2)System是在不同的环境下的行为都是一致的,一直进行日志的输出的,但是有的情况下,我们是要屏蔽日志的输出的,但是正常的日志是开发环境尽可能打印多的日志,而在生产环境里面尽量打印一些比较关键的日志,还知道哪个类的那些代码,打印日志更全,比如说时间啥的,上线屏蔽掉一些没用的日志,我们可以通过日志框架设置日志级别来屏蔽一些日志的输出;
3)日志是打印在控制台上面的,没有被永久保存下来保存的,再次重启程序,上一个错误日志是没有被保存下来的;
fatal是当程序被迫终止后才会打印此日志
@Controller public class JavaController { //1.先获取到日志对象 private static Logger logger= LoggerFactory.getLogger(JavaController.class);//里面传入的参数表示我们在哪个类中打印日志;@RequestMapping("/java100")@ResponseBody//表示给浏览器返回一个接口而不是页面public String run(String name){ //2.调用这个方法就可以成功的向控制台打印日志,使用日志框架提供的方法进行打印logger.info("我们已经成功地执行了run方法");return name+"是我";} }
在最后一行,上面是打印的日志
2022-10-24 16:51:29.403 INFO 64020 --- [nio-8080-exec-1] com.example.demo.UserController : 我已经成功执行了方法
日志打印时间段(精确到毫秒之后)日志级别线程ID线程名称包名内容日志内容(日志输出信息)
日志级别:日志级别越低,打印的日志是越多的,是为了筛选符合目标的日志信息,是为了控制相同的代码在不同的生产环境有不同的行为,我们只需要在代码不变的情况下,在配置文件里面把代码直接进行修改就好了,我们就可以过滤掉一些不符合级别的日志了,日志缩小了,IO次数小了,程序执行效率就变高了
日志级别:
1)日志级别可以筛选出一些重要的信息,比如说设置日志级别是error,那么就可以看到程序的报错日志了,对于普通的调试日志和业务日志就可以忽略了,从而帮助开发者节省信息筛选的时间;
2)日志级别可以控制在不同的环境下面,一个程序是否需要打印日志,比如说开发环境我们需要很详细的信息,而生产环境下为了保证性能和安全性就可以输出更少的日志,而日志的级别就可以实现此需求;
1)trace:轻微痕迹,他是最轻量的(级别日志)
2)debug:调试日志,需要调试的关键信息展示
3)info:普通信息,普通的打印信息
4)warn:警告,不影响使用,但是需要注意的信息
5)error:错误日志,级别较高的错误日志信息
6)fatal:致命的日志,由于代码异常导致程序退出的执行的事件,不支持程序进行打印,程序直接崩溃,是由系统直接输出的;
7)日志的级别就是为了筛选信息和过滤信息的,是不能看比他级别底的日志,比如说我现在设置日志级别是info,那么我所看到的日志的级别的信息只能是info,warn,error,fatal,不能看到info以下的级别信息,当我进行设置日志级别是warn只能看到error和fatal输出的日志信息,自定义输出的日志是非常完善和详细的,和系统日志输出的内容是相同的
@Controller public class JavaController {private static Logger logger= LoggerFactory.getLogger(JavaController.class);@RequestMapping("/java100")@ResponseBody//表示给浏览器返回一个接口而不是页面public String run(String name){logger.trace("日志级别是trace");logger.debug("日志级别是debug");logger.info("日志级别是info");logger.warn("日志级别是warn");logger.error("日志级别是error");return name+"是我";} }
最终输出结果:
日志级别是info
日志级别是warn
日志级别是error
最后输出结果打印比SpringBoot默认日志级别(info)高的日志:
如果说咱们在生产环境,就可以提高日志的级别了,想要看到所有的日志级别,就要设置默认级别是trace,因为当前默认的日志输出界别是info,程序只会输出等于当前级别或者是大于当前级别的信息,所以说比info小的级别最终我们是看不到的
我们越往下收到的消息越少,比如说设置了warn就只能收到warn,error和fatal级别的日志了
1)门面模式:真正的进行操作之前有一个代理对象,所有的类进行操作的时候,操作的肯定是代理对象而不是最终的一个类,就类似于JDBC,不管你底层连接的是MYSQL数据库还是Oracle数据库还别的数据库统统不管,最上层就是JDBC,就算框架变了,我的最上面的写法就是保持不变的,保持一致性;
2)所以说不管最后最底层的日志实现框架使用的是log4j,1/2,JUL,还是lobback,最终的最上层的写法都是固定的,获取到的日志对象打印日志的代码是永远不会发生改变的,其实最后真正打印日志不是SLF4J,SLF4J只是驱动了某一个日志实现进行打印的,可能是logback,也有可能是log 4j 1/2,假设后面的logback出现了巨大的漏洞,底层换成log 4j 1/2就可以了,用户看到的就是代理操作的对象就是slf4j,底层实现的就是底层类(logback等等)
3)门面模式又叫外观模式,提供了一个统一的接口,提供了一个统一的接口,用来访问子系统中的一群接口其主要特征是定义了一个高层接口,让子系统更容易使用,属于结构性模式
我们的SLF4J只是一个代理而已,真正决定日志打印还是日志品质以及漏洞的不是SLF4J,SLF4J只是一个中间人,而是决定最终使用的JUL还是logback,用户只是可以感知到的操作的是SLF4J;
SLF4J和lombok都是常用的日志框架,都被内置到Spring里面
他的一个过滤规则:比yml文件里面的日志默认级别低的日志就会被忽略掉,但是正常情况下日志的默认过滤级别是info
设置日志的级别还是在咱们的配置文件里面设置:
1)设置全局的日志级别:
在properties里面进行设置:logging.level.root=trace 在yml里面进行设置: logging:level:root:trace
2)在配置文件里面设置日志级别:设置指定目录的日志级别
logging:level:com:example:demo:UserController: info #设置com.example.demo包底下的UserController包下打印的日志界别是info
logging.level.com.example.demo.Tl=trace #这是定位到包的,不要写root
日志级别设置通常设置到文件夹级别
这样所有的日志输出级别就都可以进行打印了
最终结果是当我们在浏览器上面访问URL的时候,UserController会自动打印日志信息,况且会把trace以上的日志级别的信息全部进行输出,因为我们已经设置了UserController类里面的日志级别是trace了
存储日志和实现日志持久化
以上的SpringBoot的日志都是输出在控制台上面的,但是如果说我们想要在生产环境的情况下直接保存下来到磁盘的某一个位置,以便后面出现问题以后去追溯问题,我们把日志保存下来的这个过程就叫做日志持久化,它一共有两种实现方式:
1)在配置文件里面设置日志的保存路径,当设置了保存路径之后,那么日志就会自动地进行持久化操作,日志文件名字就是SpringBoot自动创建文件的名字(path);
2)在配置文件里面设置日志保存的名称,日志会自动地进行持久化(name);
1)设置日志的保存路径:
设置日志的保存路径:spring boot会按照自己的格式生成日志文件并到对应的我们所指定的目录,下面的结果就是说在D盘下面的loggs目录会生成一个spring.log的文件
错误的使用方式:
此时我们要注意一个问题:在配置文件里面写日志持久化路径的时候:D:\Data\---->"\D"会被SpringBoot认为是一个特殊的字符,而非目录,所以说日志持久化不会成功 那么如何才可以正确保存呢? 1)logging.file.path:D:/Data/ 2)logging.file.path:D:\\Data\\
默认情况下springboot会有一个最大的日志大小限制,如果日志的文件大于默认的最大日志大小,那么SpringBoot会重新启动一个日志文件进行保存,我们可以在yml文件里面进行设置:max-size属性,默认情况下是20KB,自动进行分割
logging.level.com.example.demo.AL=trace//设置demo包底下的AL包里面的类日志级别全部是trace logging.file.path=D:\
所以说当我们的程序部署到linux服务器上面,我们还是可以通过设置配置文件的方式来保存我们的日志
2)进行设置日志的保存文件名称:springboot会按照你进行设置的文件来进行保存日志
logging:file:max-size: 2MBname: D:/loggs/SpringBoot.log#这样就可以修改文件名了
通过application.properties配置文件这么写:
之前已经保存的日志是没有被覆盖掉的,而是从文件尾进行追加,重启项目之后,不是直接进行覆盖的
logging.file.name=D://SpringMVC//SpringBoot.log 要指定文件的全路径+文件名
小练习:
将Controller包底下的error级别的以上的日志保存在log1.log下面,将Service底下面的warn级别以上的日志保存在log2.log目录下面;
1)针对Controller包和Service包设置不同的日志级别;
2)针对每一个包设置文件存储路径;
Logger ger=LoggerFactory.getLogger(类名.class)
这么写是很繁琐的,况且我们如果需要在要把每一个类打印日志对象,那么这个代码就需要在每一个类里面都要进行添加一遍上述代码,这当然也是很麻烦的,我们还有一些更为简化的日志输出方式,使用lombok来进行更简单的输出日志;
更加简单的打印自定义日志而不依靠日志对象:通过注解
1)添加lombock框架支持,也是一个准备工作
1.1)创建项目的时候已经把lombok添加进来了;
1.2)使用插件完成SpringBoot外部框架的注入,下载EditStarters插件,这个插件是在SpringBoot中快速添加框架依赖的插件,右键点击generate,之后弹出界面的版本号是不可以进行修改的,我们在search里面直接进行搜索你要添加的依赖,进行双击就可以了,selected下面是当前项目中存在的所有依赖;
2)使用@slf4j注解输出日志
我们接下来使用更简单的方式来进行获取日志类并进行打印完整日志,lombok注解
添加lombok框架,通过@slf4j注解来进行获取到日志对象,这样默认就会得到一个log对象
logging:file:max-size: 2MBname: D:/loggs/Spring.loglevel:root: info#整个项目的日志级别是info
@Service @Slf4j//引入日志框架 public class UserService {@PostConstructpublic void PostConstruct(){log.trace("我是日志");log.error("我是UserService下的日志");} }
1)相当于我们加上了@SLF4J之后就代替了
private static Logger logger= LoggerFactory.getLogger(JavaController.class);
2)注意:使用@SLF4J注解之后,我们在程序中直接使用log对象就可以进行输出日志,况且只有使用log对象才可以进行输出,自动提供log对象
3)加上Controller修饰的类里面使用路由地址才可以被浏览器访问到,咱们在Controller类里面调用Service层
lombok的原理以及常见注解:不影响程序执行的性能
在项目进行编译之前,lombock就可以把注解生成我想要的代码,比如说Getter和Setter,直接变成Setter方法和Getter方法
1)lombok是在编译时期搞事情的:.java代码+lombok,编译生成字节码,在JVM中进行加载运行,咱们不需要手动写Setter和Getter方法的
2)因为lombok会自动地在编译时期将我们的@Setter和@Getter注解进行引入,进一步说就是将注解替换成对应的字节码,本质上JVM是来进行识别.class文件也就是target目录;
3)查看target中的对应程序生成的.class文件就可以了,idea会自动将字节码转化成肉眼可见的JAVA源代码了,但是实际上target目录实际上存储的时候并不是以JAVA源代码来进行存储的,是以字节码来进行存储的,只不过是IDEA怕程序员看不懂,才来进行适配的,我们查看这个字节码发现,编译时期的注解都没有了,相应替换的是对应的注解对应的字节码;
3)SLF4J生成的变量就是log;
@Getter @Setter @ToString
@EqualsAndHashCode,自动添加equals和hashcode方法
@NoArgsConstructor,自动添加无参构造方法
@AllArgsConstructor,自动添加全属性构造方法,顺序按照属性的定义顺序
@NonNull,属性不可以为空
@Sif4j:添加一个为log的日志
相关文章:

SpringBoot日志文件
日志有什么用? 1)快速的排查和定位问题,直接看报错信息; 2)进行记录用户登录的信息记录业务功能日志方便分析用户是正常登录还是暴力破解用户; 假设我们在这个登录程序中没有写反暴力破解的机制,比如说用户输入密码六次…...

R语言读取Excel表格数据并绘制多系列柱状图、条形图
本文介绍基于R语言中的readxl包与ggplot2包,读取Excel表格文件数据,并绘制具有多个系列的柱状图、条形图的方法。 首先,我们配置一下所需用到的R语言readxl包与ggplot2包;其中,readxl包是用来读取Excel表格文件数据的&…...

【操作系统】操作系统IO技术底层机制和ZeroCopy
1.DMA技术详解 (1)应用程序 从 磁盘读写数据 的时序图(未用DMA技术前) (2)什么是DMA 技术 (Direct Memory Access) 直接内存访问,直接内存访问是计算机科学中的一种内存访问技术。…...

给你的边框加点渐变
目录前言border-imageborder-image实现background父子divbackgorund一个div一个伪元素background-clip🧨🧨🧨 大家好,我是搞前端的半夏 🧑,一个热爱写文的前端工程师 💻. 如果喜欢我的文章&…...

【目标检测】如何使用Yolov8
如何使用Yolov8一、前言二、用法2.1 安装2.2 使用方法2.3 模型2.3.1 目标检测2.3.2 实例分割2.3.3 分类一、前言 一种易于使用的新的对象检测模型。 由 Ultralytics 开发的 Ultralytics YOLOv8 是一种尖端的、最先进的 (SOTA) 模型: https://github.com/ultralyt…...
NVM安装、配置环境、简单使用
nvm 是Node.js 的版本管理工具,可以在同一台电脑上安装多个Node.js版本灵活切换。 安装# sudo curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash 其中0.39.0可以替换为当前最新的版本号。 配置环境变量# cd ~touch .bash_profile…...

【SPSS】数据预处理基础教程(附案例实战)
🤵♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞Ǵ…...
某饿了么APP最新版逆向分析(二):加密参数初探
二、分析加密参数 说做就做,这边用的python进行模拟请求 万事俱备只欠东风,点击run 发现报错了 怎么回事? 明明请求的内容和抓包的内容完全一致 怎么没有返回我们想要的数据 报错内容为参数错误 因此我就想可能是请求体有参数加密 我…...

程序的编译与链接(预处理详解)+百度面试笔试题+《高质量C/C++编程指南》笔试题
本篇重点介绍程序的编译与链接过程中的预处理阶段,将详细的介绍在预处理阶段会发生什么,以及讲解有关百度该内容的面试笔试题和源于《高质量C/C编程指南》的笔试题。一.【预处理详解】①预定义符号②#define2.1 #define 定义标识符注意:2.2 #…...

全解析 ESM 模块语法,出去还是进来都由你说了算
模块语法是ES6的一个重要特性,它的出现让JavaScript的模块化编程成为了可能。 在JavaScript中可以直接使用import和export关键字来导入和导出模块,但是这种语法并不是ES6的标准,而是ESM(ECMAScript Module)模块语法的…...

MATLAB 粒子群算法
✅作者简介:人工智能专业本科在读,喜欢计算机与编程,写博客记录自己的学习历程。 🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心&…...

java微信小程序音乐播放器分享系统
随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,音乐播放器小程序被用户普遍使用,为方便用户能够可以随时进行音乐播放器小程序的数据信息管理,特开发了基于音乐播放器小程序…...
VS各版本VC各版本对应关系
Visual Studio 经过多年的发展,有许多版本,经常我们在拿到一份代码时不知道对应的VS版本 这时候可以打开工程目录下的vcproj/vcxproj文件,如下所示 <?xml version"1.0" encoding"utf-8"?> <Project DefaultT…...

如何处理“WLAN没有有效的IP配置”这一问题?
🚀write in front🚀 📜所属专栏:暂无 🛰️博客主页:睿睿的博客主页 🛰️代码仓库:🎉VS2022_C语言仓库 🎡您的点赞、关注、收藏、评论,是对我最大的…...

ElasticSearch-学习笔记05【SpringDataElasticSearch】
Java后端-学习路线-笔记汇总表【黑马程序员】ElasticSearch-学习笔记01【ElasticSearch基本介绍】【day01】ElasticSearch-学习笔记02【ElasticSearch索引库维护】ElasticSearch-学习笔记03【ElasticSearch集群】ElasticSearch-学习笔记04【Java客户端操作索引库】【day02】Ela…...

【GlobalMapper精品教程】045:空间操作(2)——相交(Intersect)
GlobalMapper提供的空间分析(操作)的方法有:交集、并集、单并集、差异、对称差集、相交、重叠、接触、包含、等于、内部、分离等,本文主要讲述相交工具的使用。 文章目录 一、实验数据二、符号化设置三、相交运算四、结果展示五、心灵感悟一、实验数据 加载配套实验数据(…...

Android 一体机研发之修改系统设置————自动锁屏
Android 一体机研发之修改系统设置————屏幕亮度 Android 一体机研发之修改系统设置————声音 Android 一体机研发之修改系统设置————自动锁屏 修改系统设置系列篇章马上开张了! 本章将为大家细节讲解自动锁屏。 自动锁屏功能,这个可以根据…...

七天实现一个go rpc框架
目录rpc协议目的关于RPC和框架服务端与消息编码确保接口的实现消息的序列化与反序列化通信过程服务端的实现main 函数支持并发与异步的客户端Call 的设计实现客户端服务注册(service register)通过反射实现 service集成到服务端超时处理创建连接超时Client.Call 超时服务端处理…...

EMQX Cloud Serverless 正式上线:三秒部署、按量计费的 MQTT Serverless 云服务
近日,全球领先的开源物联网数据基础设施软件供应商 EMQ 正式发布了 MQTT Serverless 云服务 —— EMQX Cloud Serverless 的 Beta 版本,开创性地采用弹性多租户技术,用户无需关心服务器基础设施和服务规格伸缩所需资源,仅用三秒即…...
快速排序 容易理解的版本
package huaweiod.排序算法;import java.util.Arrays;public class 快速排序 {public static void main(String[] args) {int[] arr {9,8,3,5,6,7,8,9};mysort(arr, 0, arr.length - 1); // myprint(arr," ");}private static void myprint(int[] arr, Strin…...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...

数据结构:递归的种类(Types of Recursion)
目录 尾递归(Tail Recursion) 什么是 Loop(循环)? 复杂度分析 头递归(Head Recursion) 树形递归(Tree Recursion) 线性递归(Linear Recursion)…...
DiscuzX3.5发帖json api
参考文章:PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下,适配我自己的需求 有一个站点存在多个采集站,我想通过主站拿标题,采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...

JDK 17 序列化是怎么回事
如何序列化?其实很简单,就是根据每个类型,用工厂类调用。逐个完成。 没什么漂亮的代码,只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...

李沐--动手学深度学习--GRU
1.GRU从零开始实现 #9.1.2GRU从零开始实现 import torch from torch import nn from d2l import torch as d2l#首先读取 8.5节中使用的时间机器数据集 batch_size,num_steps 32,35 train_iter,vocab d2l.load_data_time_machine(batch_size,num_steps) #初始化模型参数 def …...