前言
线上呈现问题,你的第一反馈是什么?
如果是我的话,第一工夫想的应该是查日志:
if…else 到底进入了哪个分支?
要害参数是不是有缺失?
入参是不是有问题,没做好校验放进去了?
良好的日志能帮咱们疾速定位到问题所在,坑你的货色往往最为有形,良好的日志就是要让这些玩意无所遁形!
日志级别
Java 利用中,日志个别分为以下 5 个级别:
ERROR 错误信息
WARN 正告信息
INFO 个别信息
DEBUG 调试信息
TRACE 跟踪信息
1)ERROR
ERROR 级别的日志个别在 catch 块外面呈现,用于记录影响以后线程失常运行的谬误,呈现 Exception 的中央就能够思考打印 ERROR 日志,但不包含业务异样。
须要留神的是,如果你抛出了异样,就不要记录 ERROR 日志了,应该在最终的中央解决,上面这样做就是不对的:
try {
int i = 1 / 0;
} catch (Exception e) {
log.error(“ 出错了,什么错我不晓得,啊哈哈哈!”, e);
throw new CloudBaseException();
}
2)WARN
不应该呈现,然而不会影响以后线程执行的状况能够思考打印 WARN 级别的日志,这种状况有很多,比方:
各种池(线程池、连接池、缓存池)的应用超过阈值,达到告警线
记录业务异样
呈现了谬误,然而设计了容错机制,因而程序能失常运行,但须要记录一下
3)INFO
应用最多的日志级别,应用范畴很广,用来记录零碎的运行信息,比方:
重要模块中的逻辑步骤出现
客户端申请参数记录
调用第三方时的参数和返回构造
4)DEBUG
Debug 日志用来记录本人想晓得的所有信息,经常是某个功能模块运行的详细信息,曾经两头的数据变动,以及性能信息。
Debug 信息在生产环境个别是敞开状态的,须要应用开关治理(比方 SpringBoot Admin 能够做到),始终开启会产生大量的 Debug,而 Debug 日志在程序失常运行时大部分工夫都没什么用。
if (log.isDebugEnabled()) {
log.debug(“ 开始执行,开始工夫:[{}],参数:[{}]”, startTime, params);
log.debug(“ 通过计算,失去参数 1:[{}],参数 2:[{}]”, param1, param2);
log.debug(“ 最初处理结果:[{}]”, result);
}
5)TRACE
特地具体的零碎运行实现信息,业务代码中个别不应用,除非有非凡的意义,不然个别用 DEBUG 代替,事实上,我编码到当初,也没有用过这个级别的日志。
应用正确的格局
如果你是这样打印日志的:
log.info(“ 依据条件 id:{}” + id + “ 查问用户信息 ”);
不要这样做,会产生大量的字符串对象,占用空间的同时也会影响性能。
正确的做法是应用参数化信息的形式:
log.info(“ 依据条件 id:[{}],查问用户信息 ”, id);
这样做除了能防止大量创立字符串之外,还能明确的把参数隔离进来,当你须要把参数复制进去的时候,只须要双击鼠标即可,而不是用鼠标缓缓对准再划拉一下。
这样打进去的日志,可读性强,对排查问题的帮忙也很大!
小技巧
1)多线程
遇到多个线程一起执行的日志怎么打?
有些零碎,波及到并发执行,定时调度等等,就会呈现屡次执行的日志混在一起,出问题不好排查,咱们能够把线程名打印进去,或者加一个标识用来表明这条日志属于哪一次执行:
if (log.isDebugEnabled()) {
log.debug(“ 执行 ID=[{}],解决了 ID=[{}]的音讯,处理结果:[{}]”, execId, id, result);
}
2)应用 SpringBoot Admin 灵便开关日志级别
写在最初
一开始写代码的时候,没有标准日志的意识,不论哪里,都打个 INFO,打印进去的货色也没有思考过,有没有意义,其实让本人踩了不少坑,加了不少班,回过头,我想对学习期间的我说一句:”能让你加班的货色,都藏在各种细节里!写代码之前,先好好学习如何打日志!