事故代码

直入主题,生产环境日志级别为warn,请看如下这行代码:

LOGGER.info("the DTO info: {}", JSON.toJSONString(DTO));

先做个小调查,你觉得这段代码会不会有问题:

如果你的答案为“有问题”,并且你有充足的理由,那么这篇文章已经没有往下看的必要了,因为你已经掌握了笔者此文要传达的知识点。如果你的答案为“没有问题”或者“无法分辨”,那么,请继续往下看。

原因分析

这段代码主要有两个需要注意的地方:

  1. 日志级别为info,而线上环境是warn级别。我们可以得出结论,线上环境肯定不会输出这行日志。

  2. 打印日志的行为中有JSON序列化动作。

第二点是此文的关键。我们假设DTO是一个很小的对象,JSON序列化时间以及开销可以忽略不计,那么这行代码依然没有问题。但是,如果DTO是一个很大的对象,比如10k,甚至100k,即使快如fastjson,其耗时依然高达数百毫秒,并且非常消耗CPU。如果是在高并发的系统中,这么大的开销完全不可接受,甚至可能就会拖垮整个系统。

有同学就会说了,我不是info日志么,为什么还会执行这行代码?请继续往下看。我们首先看一下slf4j中logger.info()这个方法是如何申明的:第二个参数为Object类型。我们的代码中传递给第二个参数的值为:JSON.toJSONString(DTO),很明显这行代码是传递一个String类型的字段给Object arg。那么String如何来呢?答案也很明显,必须先执行JSON序列化才能得到String。那么logger.info这个info在什么时候起作用呢?答案是它只能在输出日志这个动作时起作用:

public void info(String format, Object arg);

解决方案

如何解决这个问题?很简单,在输入日志时加个级别判断(需要说明的是,这种规范很容易被忽略,比如项目成员更替时,很容易引入有问题的代码。所以笔者写了一段脚本:扫描所有Java代码,如果logger.info()中有JSON序列化动作,那么必须判断优先级后才能输出日志。即可以简单的认为它的前一行代码必须是logger.isInfoEnabled()。如果你的项目有CICD环境,那么把这段脚本集成到扫描规范中,才是解决这个问题最完美的方案):

if(LOGGER.isInfoEnabled()) {LOGGER.info("the DTO info: {}", JSON.toJSONString(DTO));
}

当然,需要说明的是,通过上面的分析,如果我们的打印日志那行代码中没有JSON序列化等耗时动作的话,那么日志级别判断就没必要了,比如下面这行代码:

String reqId = "...";
String msg = "...";
LOGGER.info("the DTO info: {}", msg);
热门内容:求你别再用swagger了,给你推荐几个在线文档生成神器IntelliJ IDEA官方宣布中文汉化包正式发布低代码 yyds再见Spring!下一个开源框架更香!最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

明天见(。・ω・。)ノ♡

万万没想到! logger.info() 还能导致线上故障?相关推荐

  1. ora 00900 已编译但有错误_技术分享|万万没想到!编译错误竟然还没灭绝???

    CodeWisdom-技术分享 万万没想到!编译错误竟然还没灭绝??? 复旦大学CodeWisdom团队的代码分析和挖掘小组针对开源软件项目持续集成过程中出现的编译错误,进行了大规模的经验研究.该研究 ...

  2. 万万没想到,我的炼丹炉玩坏了

    一只小狐狸带你解锁NLP/ML/DL秘籍 作者:夕小瑶 前记 众所周知,夕小瑶是个做NLP的小可爱. 虽然懂点DL框架层知识,懂点CUDA和底层,但是我是做算法的哎,平时debug很少会遇到深度学习框 ...

  3. 万万没想到系列,世界上最知名的失败建筑设计合集!

    ​ 大家好,这里是建模助手. 我们生活在由建筑包围的世界里,生活的面貌造就了建筑的多样性.而矗立的建筑也无言的记录着时代,尤其是一些建筑大师们的作品,可谓是集艺术和美学于一体的一流名作. 但,这不是凡 ...

  4. 显卡暴涨,这我万万没想到啊

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 梦晨 晓查 发自 凹非寺  量子位 报道 | 公众号 QbitAI ...

  5. 万万没想到,坤坤洗白的第一步是周琦…

    前晚(2日)中国男篮与波兰队的关键一战惜败后,几乎所有中国球迷都在哭"琦","琦"到一夜未眠. 周琦关键时刻边线发球失误,硬生生把中国男篮提前出线的jio给拖了 ...

  6. 科学家们竟用乐高观察细胞,网友:万万没想到啊

    杨净 子豪 发自 凹非寺 量子位 报道 | 公众号 QbitAI 玩乐高还能玩出个显微镜?! 原本以为是一个普普通通的玩具. 没想到,还真能当成显微镜来用,是能看到细胞的那种. 真·高端新玩法! 比如 ...

  7. 显卡暴涨,等等党输了,这我万万没想到啊

    梦晨 晓查 发自 凹非寺  量子位 报道 | 公众号 QbitAI 万万没想到,去年信心满满准备好钱包要买30系显卡的我,现在连1660Ti都快买不起了. 不仅官方原价3899的RTX 3070,一路 ...

  8. 2015年第21本:万万没想到,用理工科思维理解世界

    <万万没想到:用理工科思维理解世界>这本书好像是从amazon排行榜中发现的,先是下载了电子版,竟然是一个博客(学而时嘻之)的大合集,可能是网上的某人用作者的博客制作而成的,共有123章! ...

  9. python这个软件学会能做什么工作-万万没想到,学会Python即使不做程序员都能月入过万!...

    昨天,我公司面试了1个同学,应聘新媒体运营,专业能力还不错.他简历上技能栏还写着会Python,我问了他一个通过爬虫采集数据的问题,他都顺畅的答出来了. 最后聊薪资时,他说期待7000,我直接给他开了 ...

最新文章

  1. yolo如何降低loss_从未看过如此通俗易懂的YOLO系列
  2. java反射 int_java反射如何调用参数为int的方法?
  3. mysql 分布式 安装_mysql分布式集群安装-阿里云开发者社区
  4. 【图像分类】没有人工收银,吃饭买单全自动化,是谁的功劳?
  5. “让Keras更酷一些!”:层与模型的重用技巧
  6. 第三次学JAVA再学不好就吃翔(part94)--HashMap嵌套HashMap
  7. 怎么用计算机弹出soldout,SOLDOUT2游戏新手攻略玩法全面介绍
  8. 阿里巴巴对Java编程【单元测试】的规约
  9. leetcode283.移动零
  10. LeetCode 322. 零钱兑换(DP)
  11. mysql区间段_解决针对MySQL中对于某一个区间段范围的数据更新的情况
  12. java 字符串池 原理_《Java虚拟机原理图解》1.2.2、Class文件中的常量池详解(上)...
  13. 局域网文件服务器单独文件夹加密,局域网 如何给共享文件夹加密
  14. 一名IT民工开通博客
  15. 数据库load data命令批量插入txt文件的数据
  16. c语言您的验证码代码,c国际短信接口_c国际验证码接口_c国际手机验证接口_国际短信代码示例_达信通...
  17. 韦东山嵌入式第一期学习笔记DAY_4——8_3编写第1个程序点亮LED
  18. java.lang.UnsupportedClassVersionError: org/apache/activemq/spring/ActiveMQConnectionFactory : Unsup
  19. vue-router.esm-bundler.js?6c02:1474 Uncaught TypeError: Cannot read property ‘forEach‘ of undefined
  20. 《华仪酒店管理系统》项目研发性总结

热门文章

  1. Java获取文件的目录_Java实现读取某个路径下的文件目录
  2. python2.7 Cheetah You don't have the C version of NameMapper installed
  3. Behave step matcher
  4. OD使用教程6 - 调试篇06|解密系列
  5. 不改文件名的情况下上传突破
  6. 云游戏、VR、AI,云计算给元宇宙提供了哪些想象力?
  7. DeepMind 的新强化学习系统,是迈向通用人工智能的一步吗?
  8. WAIC汇聚全球顶级科学家,畅谈人工智能的未来挑战与突破
  9. ​中国自动驾驶技术有多强?你可能还不知道
  10. 关于正则表达式,这篇都讲清楚了