Java中记录日志方式比较及相关建议

一、记录日志的几种方式比较

为了测试,我在测试类中写了七种打印方式,分别如下:

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class ErrorLogTest {@Testpublic void ss(){try{float xx= 1/0;log.info("xx:{}",xx);}catch (Exception e){log.info("======================第一种打印LogExceptionStackUtil.logExceptionStack(e)======================");log.error("异常:{}",LogExceptionStackUtil.logExceptionStack(e));log.info("======================第二种打印e======================");log.error("异常:{}",e);log.info("======================第三种打印e.printStackTrace()======================");e.printStackTrace();log.info("======================第四种打印e.getMessage()======================");log.error("异常:{}",e.getMessage());log.info("======================第五种打印e.getStackTrace()======================");log.error("异常:{}",e.getStackTrace());log.info("======================第六种打印e.toString()======================");log.error("异常:{}",e.toString());log.info("======================第七种打印System.out.println======================");System.out.println("异常:{}"+e);}}}

我在工程中使用的是logback框架进行日志记录。
注意:一定要让spring容器启动起来,要不然你会苦恼得发现日志文件没生成(@RunWith和@SpringBootTest注解不要删)。

运行起来后,先给大家总结下效果吧:

方式效果
log.error(“异常:{}”,LogExceptionStackUtil.logExceptionStack(e));会打印完整日志,且打印的报错行和具体日志的开始在同一行
log.error(“异常:{}”,e);会打印完整日志,但打印的报错行和具体日志的开始不在同一行,如果用某些特殊搜索,会遗漏完整日志
e.printStackTrace();只在控制台打印了,日志文件中没有记录
log.error(“异常:{}”,e.getMessage());没有异常类型,只有异常的简单信息
log.error(“异常:{}”,e.getStackTrace());没有异常类型,只会打印从哪一行抛出的
log.error(“异常:{}”,e.toString());包括异常类型和异常的简单信息
System.out.println(“异常:{}”+e);只在控制台打印了(包括异常类型和异常的简单信息),日志文件中没有记录

日志文件节选:

2022-02-21 17:13:07.392 [main] INFO  com.my.demojava.controller.ErrorLogTest.ss line:31  - ======================第一种打印LogExceptionStackUtil.logExceptionStack(e)======================
2022-02-21 17:13:07.393 [main] ERROR com.my.demojava.controller.ErrorLogTest.ss line:32  - 异常:java.lang.ArithmeticException: / by zeroat com.my.demojava.controller.ErrorLogTest.ss(ErrorLogTest.java:28)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)此处略去30行
2022-02-21 17:13:07.394 [main] INFO  com.my.demojava.controller.ErrorLogTest.ss line:33  - ======================第二种打印e======================
2022-02-21 17:13:07.397 [main] ERROR com.my.demojava.controller.ErrorLogTest.ss line:34  - 异常:{}
java.lang.ArithmeticException: / by zeroat com.my.demojava.controller.ErrorLogTest.ss(ErrorLogTest.java:28)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)此处略去30行
2022-02-21 17:13:07.397 [main] INFO  com.my.demojava.controller.ErrorLogTest.ss line:35  - ======================第三种打印e.printStackTrace()======================
2022-02-21 17:13:07.399 [main] INFO  com.my.demojava.controller.ErrorLogTest.ss line:37  - ======================第四种打印e.getMessage()======================
2022-02-21 17:13:07.399 [main] ERROR com.my.demojava.controller.ErrorLogTest.ss line:38  - 异常:/ by zero
2022-02-21 17:13:07.399 [main] INFO  com.my.demojava.controller.ErrorLogTest.ss line:39  - ======================第五种打印e.getStackTrace()======================
2022-02-21 17:13:07.399 [main] ERROR com.my.demojava.controller.ErrorLogTest.ss line:40  - 异常:com.my.demojava.controller.ErrorLogTest.ss(ErrorLogTest.java:28)
2022-02-21 17:13:07.400 [main] INFO  com.my.demojava.controller.ErrorLogTest.ss line:41  - ======================第六种打印e.toString()======================
2022-02-21 17:13:07.400 [main] ERROR com.my.demojava.controller.ErrorLogTest.ss line:42  - 异常:java.lang.ArithmeticException: / by zero
2022-02-21 17:13:07.400 [main] INFO  com.my.demojava.controller.ErrorLogTest.ss line:43  - ======================第七种打印System.out.println======================

总结:最推荐的做法是第一种打印方式:log.error(“异常:{}”,LogExceptionStackUtil.logExceptionStack(e));

public class LogExceptionStackUtil {public static String logExceptionStack(Throwable e) {StringWriter errorsWriter = new StringWriter();e.printStackTrace(new PrintWriter(errorsWriter));return errorsWriter.toString();}
}

或者使用最常用的第二种打印方式:log.error(“异常:{}”,e);
如果你不想略去详细信息,请不要用第四、第五、第六种;
最最最不应该使用的是第三种e.printStackTrace(),因为它压根不会在日志文件里打印,且容易堆栈溢出,造成第二节的严重后果,见下。

二、e.printStackTrace()为什么不要用

1)不会打印到日志文件中,生产环境排查问题的噩梦

只会打印在控制台,如果生产环境有问题,莫非要连上人家的环境启动项目?或者临时改代码?(说多了都是泪)

2)占用内存,严重时造成系统卡顿或挂掉

具体原因如下流程:

短时间内大量请求访问此接口 -> 
代码本身有问题,很多情况下抛异常  -> 
e.printStackTrace() 来打印异常到控制台 -> 
产生错误堆栈字符串到字符串池内存空间 -> 
此内存空间一下子被占满了 -> 
开始在此内存空间产出字符串的线程还没完全生产完整,就没空间了 ->  
大量线程产出字符串产出到一半,等在这儿-> 
相互等待 ->
等内存->
锁死了->
整个应用挂掉、访问没响应

参考文章:java中e.printStackTrace()不要使用,请使用logger记录

3)日志交错混合,不易读

printStackTrace()默认使用了System.err输出流进行输出,与System.out是两个不同的输出流,那么在打印时自然就形成了交叉。再就是输出流是有缓冲区的,所以对于什么时候具体输出也形成了随机。

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

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

相关文章

word打字覆盖后面的字 教你word打字覆盖后面的字怎么办

我之所以会知道解决word打字覆盖后面的字这个问题的方法,是因为之前遇到这个情况的时候也不知道该如何处理了,不过幸亏一个朋友告诉了我解决这个问题的办法,然后我就多了解了一下子这方面的知识,所以我现在就将解决这个问题的方法…

Windows7系统资源怎么看?

在平时的工作中,我们会安装很多软件,虽然用完卸载了,但是还是会有残留占用资源,于是我们就得去看一下系统资源,可是很多用户不知道系统资源怎么看?其实方法很简单,如果你不知道Windows7系统资源…

Collectors.collectingAndThen()Collectors.collectingAndThen 去重Stream分组groupBy后取单一字段值、取列表第一个值方式

Collectors.collectingAndThen() Java 8 流的新类 java.util.stream.Collectors 实现了 java.util.stream.Collector 接口,同时又提供了大量的方法对流 ( stream ) 的元素执行 map and reduce 操作,或者统计操作。 Collectors.collectingAndThen() 函数应…

EasyBoot如何使用?EasyBoot制作多系统启动盘教程

在平时的工作中,我们会安装很多软件,虽然用完卸载了,但是还是会有残留占用资源,于是我们就得去看一下系统资源,可是很多用户不知道系统资源怎么看?其实方法很简单,如果你不知道Windows7系统资源…

问题:在使用dubbo 2.5.3之前的版本@Service来发布服务时,当该服务中有@Transactional,是无法正常发布的?

问题:在使用dubbo 2.5.3之前的版本Service来发布服务时,当该服务中有Transactional,是无法正常发布的? 解决方案: 因为事务TransactionManagement默认是使用了jdk的代理即基于接口的代理,必须改成基于类的代理,servi…

win7发现不了无线网络怎么办 win7发现不了无线网络的解决办法

今天来跟各位说说win7发现不了无线网络怎么办。 1.我们单击右下角的无线网络以打开网络和共享中心。 2.单击“更改适配器设置”。 3.在“网络连接”窗口中,如果网络连接中的无线网络显示为灰色,则右键单击“启用”。 4.在网络连接中没有无线网络连接&…

win7分辨率不能调怎么办 win7系统分辨率不能调的解决方案

win7分辨率不正常怎么回事?分辨率为什么不能调?win7分辨率不能调是什么原因?怎么来解决win7分辨率不能调的问题?现在小编就分享一篇关于win7系统分辨率不能调的解决方案。 分辨率对系统来说是相当重要的,这关系到系统桌面屏幕的清晰度,如果调得不好…

Mybatis-Plus字段策略FieldStrategy详解

文章目录一、官方文档二、字段策略介绍1、FieldStrategy作用2、FieldStrategy类型3、FieldStrategy配置全局策略配置单字段策略配置三、实战说明1.默认策略 - NOT_NULL2.忽略判断-IGNORED3.从不处理-NEVER4.字符不为空-NOT_EMPTY5.跟随全局-DEFAULT总结一、官方文档 Mybatis-P…

移动硬盘接口坏了怎么办解决教程

移动硬盘由于在使用中掉落或者经常插拔,会导致移动硬盘的接口的损坏,其实就是移动硬盘端的usb接口的损坏,而很多时候只是这个接口的焊点松动,有时候确是本身掉落金属手指导致损坏,而其实解决方法真正有效的有两种。 移…

任意门怎么用团发_衣柜门选用什么材料好?小编在这里告诉你

衣柜是美观家庭必不可少的,它我们的空间看起来更整洁。但是衣柜的材料值得我们好好考虑一下。衣柜门有哪些材质1、铝合金铝合金材质的衣柜门在日常生活中比较常见,使用得比较多。这是因为其环保性能比较好,而且十分耐用,还具有较强…

Google Gson API 介绍与使用

文章目录Gson基本操作Gson 概述与下载Gson (反)序列化 Java 对象JsonElement Json 元素JsonObject Json 对象JsonArray Json 数组JsonParser Json 解析GsonBuilder 构建 GsonJsonElement的简单说明JsonElement:JsonPrimitive:JsonNull:JsonArray:JsonObj…

移动硬盘读取速度一般是多少

移动硬盘现在已经普及很高了,几乎有存储需要的朋友都有一个移动硬盘,而且现在的移动硬盘已经升级到usb3.0的了,以前的usb2.0的移动硬盘逐渐淘汰,那么很多朋友在问移动硬盘的读取速度一般是多少算正常呢,下面就给大家测…

光功率 博科交换机_如何将交换机40G QSFP+与10G SFP+端口互连?

随着40G以太网的到来,许多企业用户开始充分利用当前的10G网络设备升级到40G网络,具体来说也就是如何将带有QSFP端口的40G交换机与现有带SFP端口的10G设备(交换机和服务器)搭配使用的问题。在本篇文章中,易天光通信(ETU-LINK)将分享三种常见的…

Gson使用Gson工具类GsonUtils(项目中要求不要使用Fastjson,原因:Fastjson存在安全漏洞)

一、概述 Gson是google提供的用来操作json数据的一个非常好用的类库。其使用范围非常的广泛,所以非常有必要对其进行系统的学习。 json是一种数据格式,确切的说是一种文本数据格式。其在网络通讯过程中的作用非常的明显。 目前大多数的网络通讯格式已经从…

浅析怎样提升win7 旗舰版系统显示质量

今天小编给大家浅析怎样提升win7 旗舰版系统显示质量,大家一起来了解下吧,具体如下: 一、打开的程序或窗口的数量尽量减少 当你打开的程序越多,Windows 所需的系统资源也就越多。请将当前没有使用的程序关闭,或缩小窗…

keil 函数最多可以传几个参数_007 函数进阶,来做一次比较正式的作业

这节课开始之前,先来解决一个小问题。最近这两节课,有人对缩进的规则不太理解,这里解释一下。如上图所示,相同的缩进代表同一个代码块,即同一个顺序执行代码段落。如果代码缩进减少,则说明当前代码块结束&a…

Win7休眠后唤醒出现黑屏的解决办法

进入睡眠状态可很好地节约电源和延长硬件的使用寿命,很多用户的电脑进入睡眠状态后,唤醒无法正常进入屏幕,而是变成黑屏的故障,怎么回事?其实出现这种情况并非什么系统故障问题,下面小编给大家分享Win7休眠后唤醒出现…

Map按照Value值进行排序的实现

Map按照Value值进行排序的实现 map.entrySet().stream().sorted(Comparator<? super T> comparator)给定一个map&#xff0c;存储一个nums数组中每一个数字存储的次数&#xff0c;最后将这个map按照value值&#xff0c;即出现的次数进行排序 第一种方式&#xff1a;返…

传授电脑蓝屏开不了机怎么办

电脑是现代社会不可缺少的重要工具&#xff0c;不仅可以帮助处理复杂的数据&#xff0c;还可以辅助教学&#xff0c;设计&#xff0c;聊天娱乐。下面&#xff0c;我就给大家介绍一下电脑蓝屏开不了机的解决方法&#xff0c;有需要就引起来了解一下吧 大家在使用电脑的时候有没…

华为核心交换如何配置源地址转换_华为三层交换机配置步骤解释资料全

word格式文档专业整理华为三层交换机配置步骤1.给交换机划分VLANVlan是虚拟局域网的意思&#xff0c;它相当于一个局域网工作组。“vlan几”可以理解成编号为几的vlan&#xff0c;比如vlan 2就是编号为2的vlan&#xff0c;只是一个编号而已&#xff0c;并不是说vlan 2的网段一定…