当前位置: 首页 > news >正文

【Java踩坑笔记】45_日志打印对象用toString,生产环境可能引发雪崩

45 | 日志打印对象用 toString,生产环境可能引发雪崩

摘要log.info("订单:{}", order)会触发order.toString(),如果toString()里拼接了大量字段或有循环引用,生产环境高并发下会引发性能雪崩。


一、问题现象

// ❌ 危险:直接打印整个对象log.info("处理订单:{}",order);// order.toString() 可能是:publicStringtoString(){return"Order{id="+id+", userId="+userId+", items="+items+", logs="+logs+...}";// 如果 items 有 1000 条,toString() 极其耗时}

现象:生产环境日志量暴增,CPU 占用升高,接口响应变慢。


二、踩坑现场

场景 1:toString() 里有集合字段

// ❌ 危险:toString() 里打印了 List@ToStringclassOrder{privateLongid;privateList<OrderItem>items;// 可能 1000 条privateList<OrderLog>logs;// 可能 500 条}

log.info("订单:{}", order)→ 触发order.toString()→ 拼接 1500 条子对象的toString()→ 一次日志耗时 500ms。

场景 2:敏感信息打印到日志

// ❌ 危险:用户密码、Token 打印到日志log.info("用户登录:{}",user);// user.toString() 包含 password

三、正确写法

3.1 只打印关键字段

// ✅ 正确:只打印关键字段log.info("处理订单:orderId={}, userId={}",order.getId(),order.getUserId());

3.2 用 Lombok @ToString 排除大字段

// ✅ 正确:排除大字段@ToString(exclude={"items","logs"})classOrder{privateLongid;@ToString.Exclude// Lombok 新版本privateList<OrderItem>items;}

3.3 敏感字段不打印

// ✅ 正确:敏感字段用 @ToString.Exclude 排除@ToStringclassUser{privateLongid;@ToString.Exclude// 排除 passwordprivateStringpassword;privateStringname;}

3.4 JSON 打印(需控制深度)

// ✅ 需要打印对象时,用 JSON 且排除敏感字段log.info("订单:{}",JsonUtils.toJson(order,"password","token"));

四、最佳实践

✅ 日志打印的 5 条铁律

  1. 不要直接打印整个对象,只打印关键字段
  2. @ToString排除大字段和集合字段
  3. 敏感字段(passwordtoken)必须排除
  4. 日志里不要用字符串拼接+),用占位符({}
  5. 生产环境关闭 DEBUG 日志(只开 INFO/WARN)

🔍 Lombok @ToString 配置

@ToString(exclude={"items","logs"},// 排除字段callSuper=false,// 不打印父类字段includeFieldNames=true// 打印字段名)classOrder{...}

五、小结

  • log.info("{}", obj)会触发obj.toString(),如果toString()拼接大字段,高并发下性能雪崩
  • 只打印关键字段,不要直接打印整个对象
  • @ToString排除大字段和集合字段
  • 敏感字段必须排除,防止泄露
  • 生产环境只开 INFO/WARN,关闭 DEBUG

下一篇预告:用 switch 忘了写 break?Java 14 之后有更好的写法—— 穿透问题(fall-through)是 C 语言遗留的设计,Java 14 的 switch 表达式彻底解决了它。

更多资料一线大厂Java面试题合集

http://www.jsqmd.com/news/1195863/

相关文章:

  • 深入解析TI C6748 DSP:架构、开发与优化实战指南
  • MATLAB中FFT频谱分析实战:从基础语法到频谱泄露与补零策略
  • TensorFlow 是由 Google 开发并开源的端到端开源机器学习框架,广泛用于构建和训练深度学习模型(如神经网络)
  • 2026年7月最新亨得利官方服务项目及价格查询|服务热线及门店地址权威信息通知 - 亨得利官方博客
  • LT8710控制器解决长距离电源线电压降问题
  • 撒尿的小孩,蚂蚁,以及沉默的天气——论人类认知的三重牢笼
  • AI聚合平台技术解析:多模型集成与Sider实战指南
  • 2026 抖音视频在线解析怎么选:零成本使用,年省360元服务费
  • 【研发类-后端开发Skills】api-patterns 技能
  • 如何用C#写一个带数据可视化的上位机
  • BIDK与MAMBO的关系:从开源项目到企业级工具的演进之路
  • 情感化文本处理技术:从字符串操作到情感分析实战
  • 2026 年|杭州汽车后市场服务企业做GEO服务商哪个好?本地服务商实力排名与行业适配选型指南 - 企业新闻快传
  • 二七大学路名表回收老店,同城最快半小时上门 - 全城热点
  • KLayout版图比对工具strmxor的顶层单元命名优化:解决LVS验证中的导航难题
  • C++14读写锁std::shared_timed_mutex原理与实战:提升多线程性能
  • 鸿蒙应用开发实战【15】— LinearGradient 线性渐变在 ArkUI 中的应用
  • UDS 操作循环:DTC状态机背后的驾驶周期逻辑
  • docker mysql主从安装-元一软件
  • AI安全通讯与受控模型发布机制解析
  • 【研发类-测试开发Skills】azure-resource-manager-playwright-dotnet 技能
  • 湖州德清县打岩石井多少钱一米,德清打井电话,莫干山民宿打井 - 瑞溪泉水利
  • 源代码论文分享|基于springboot的大创管理系统!
  • 原创角色保护系统:从DRM技术到完整技术架构实现
  • 从Hosts文件到现代网络映射:解析主机名与IP地址的底层逻辑
  • 从零手搓大模型(深挖细节GQA )现代大模型为什么不用普通 MHA
  • 鸿蒙应用开发实战【16】— bindSheet 底部弹出面板全解析
  • 2026年7月最新亨得利官方服务项目及价格查询|详细地址与服务电话权威信息声明 - 亨得利官方
  • 基于Python+爬虫的房屋租赁数据可视化系统设计与实现
  • 深入解析MOS管三个工作区及其在H桥电路中的关键应用