1.日志的定义:程序执行过程中,记录程序运行的情况的 信息
2.日志的作用:
Log 日志,主要用于记录程序运行的情况,以便于程序在部署之后的排错调试等,也有利于将这些信息进行持久化(如果不将日志信息保存到文件或数据库,则信息便会丢失)。
日志的3个注意点
1.日志级别 (程序运行哪种级别,日志才输出)
2.日志 输出的 目的地(控制台,持久化文件数据库,...)
(日志信息 输出到哪,保存到哪)
3.日志信息的格式,日志输出的格式
这些一般是在配置文件中配置,日志依赖 会去 解析 xml文件,将数据
设置到自己的 类里面去,然后去操作
jdk3以前,system.println 去打印日志信息 打印日志信息,你可以简单的理解为,system.out输出,只是你可以输出在控制台,文件里,并且可以控制日志界别,让 此级别或 更高 级别的 日志打印,简单来说,还是得我们 自己去编写 打印日志的语句,以及配合 程序运行的级别的,自动日志打印,只要我们定了 日志级别,不管是程序打印的,还是我们自己写代码打印的,都只会打印这个日志级别及其以上的日志
关于日志 level
1.共有 8 个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF
All:最低等级的,用于打开所有日志记录
Trace:是追踪,就是程序推进以下,你就可以写个 trace 输出,所以 trace 应该会特别多,
不过没关系,我们可以设置最低日志级别不让他输出
Debug:指出细粒度信息事件对调试应用程序是非常有帮助的
Info:消息在粗粒度级别上突出强调应用程序的运行过程
Warn:输出警告及 warn 以下级别的日志
Error:输出错误信息日志
Fatal:输出每个严重的错误事件将会导致应用程序的退出的日志
OFF:最高等级的,用于关闭所有日志记录
2.程序会打印高于或等于所设置级别的日志,设置的日志等级越高,打印出来的日志就越少
项目中日志记录遵守哪些原则
1.注意日志级别,尤其是 info 和 error 不能用混。
2.注意记录信息的准确性,切记日志表达不清楚。
3.注意不同的代码段日志说明不能重复。
4.捕获异常后,要及时记录异常详细信息,并把异常传递到外部。
5.时刻铭记,日志的记录是为了后期查询问题带来方便,因此重要的代码务必要记录日志。
几个错误的打日志方式:
1.不要使用 System.out.print..
输出日志的时候只能通过日志框架来输出日志,而不能使用 System.out.print… 来打印日志,这个只会打印到 tomcat 控制台,而不会记录到日志文件中,不方便管理日志,如果通过服务形式启动把日志丢弃了那更是找不到日志了。
2.不要使用 e.printStackTrace()
首先来看看它的源码:
public void printStackTrace() {
printStackTrace(System.err);
}
3.不要抛出异常后又输出日志
它其实也是利用 System.err 输出到了 tomcat 控制台
如捕获异常后又抛出了自定义业务异常,此时无需记录错误日志,由最终捕获方进行异常处理。不能又抛出异常,又打印错误日志,不然会造成重复输出日志。
try {
// ...
} catch (Exception e) {
// 错误
LOG.error("xxx", e);
throw new RuntimeException();
}
4.不要使用具体的日志实现类
5.没有输出全部错误信息
看以下代码,这样不会记录详细的堆栈异常信息,只会记录错误基本描述信息,不利于排查问题
try {
// ...
} catch (Exception e) {
// 错误
LOG.error('XX 发生异常', e.getMessage());
// 正确
LOG.error('XX 发生异常', e);
}
6.不要使用错误的日志级别
曾经在线上定位一个问题,同事自信地和我说:明明输出了日志啊,为什么找不到…,后来我去看了下他的代码,是这样的:
try {
// ...
} catch (Exception e) {
// 错误
LOG.info("XX 发生异常...", e);
}
大家看出了什么问题吗?用 info 记录 error 日志,日志输出到了 info 日志文件中了,同事拼命地在 error 错误日志文件里面找怎么能找到呢?
7.不要在千层循环中打印日志
这个是什么意思,如果你的框架使用了性能不高的 Log4j 框架,那就不要在上千个 for循环中打印日志,这样可能会拖垮你的应用程序,如果你的程序响应时间变慢,那要考虑是不是日志打印的过多了。
for(int i=0; i<2000; i++){
LOG.info("XX");
}
最好的办法是在循环中记录要点,在循环外面总结打印出来。
8.禁止在线上环境开启 debug
这是最后一点,也是最重要的一点。
一是因为项目本身 debug 日志太多,二是各种框架中也大量使用 debug 的日志,线上开启 debug 不久就会打满磁盘,影响业务系统的正常运行。
ps:Spring Boot官方推荐优先使用带有-spring的文件名作为你的日志配置(如使用logback-spring.xml,而不是logback.xml)
loback配置文件放在 class path:下即可
简单来说,日志有输出功能,有日志级别,定了日志级别,那么我们打印 log.级别,只有在 这个级别以上 的 才能输出,特别注意 log 只有 2个特点 log级别,log.级别()输出,即,只要我定了log的级别,那么当我想打印日志的时候,只能用log.定的级别以上() 才能打印出日志,而 日志的级别和 系统处的环境没有半毛钱关系,只是说,当我们系统处于某个 ”状态或者环境下,例如出异常,出错了“,这时 我们选择 对应的 log.级别() 去记录日志,这样我们 打印出来的日志 有()里面的内容,也有 我们用的 log.级别 这个级别,通过这个级别我们就知道,这个日志是在 系统什么情况下打印的,打印的内容是什么
举个例子,我们定 log的日志级别是 debug , 那么我们能用的 log.级别这能是 debug和以上的,跟系统处于什么状态没有关系,但是,正因为我们 只能 log.debug级别和以上的,也就是说,我们打印出来的 日志级别+日志内容,通过日志级别来看,我们只能 知道,哦 这是系统在 debug和以上我们打印的,而系统在 debug和以下情况的时候,我们根本无法 选用 log.debug和以下级别()的 这种去打印,我们就不能把 系统在 debug和以下的情况 给 记录下来,当然如果你说 我在 ()内容中说明也可以,但是不明了,我们打印的日志信息中 就有 日志级别+()日志内容 我们都是通过日志级别去想像 在 系统这个情况下,发生了什么内容,例如 在 debug情况下,那句sql()这记录在内容中出了问题,这样我们就知道 在 debug的时候,哪个地方的sql出现了问题,解决了 之后,那么在 debg环境下,这个地方的这句sql 就不会有问题了
说白了,在 系统出现不同问题的时候,我们用 log.级别() 去记录,级别我们要自己选择,对应这个问题所处的系统此时的环境,是debug下出错的,还是其他,例如是 debug情况下出错的,那么我们这里 log.debug(出错的地方,出错的位置),这样我们 就能通过 这个打印的这句日志,知道系统在 什么情况下,在那,错了什么错,这样我们 让系统再 处于这个情况下,去定位到这个错误,去改掉,让 系统在这个情况下,不会在出此错误,但是不代表 不会在 其他情况下的相同位置,又出现错误,这是不能保证的,我们解决的 是 那个情况下出的那个错误,,而且 我们用的 log.级别 必须是 在我们 定的 日志级别 的范围下才可以,实际定日志级别,就代表 我们这个系统,我们只想要 解决 这个级别或以上的情况下出现的错误,这个级别以下的就算出错了我们也不想解决,所以我们定了这个级别,让我们即使想用 log.这个级别以下的 都不能用
而 log的 日志级别,一般我们要用一个 文件去配置,或者在springboot的配置文件里面配置
除了,你自己打印日志,系统的各种组件,springboot源码处,也会打印日志,同样你可以改变这些组件的日志级别,因为组件的 log.级别() 底层都是写死的,你改了组件的日志级别,那么就可以控制 他们 打印的日志级别