生产环境必须用logger.error(“msg”, e)而非e.printStackTrace(),因后者仅输出到System.err且不可捕获,日志系统无法收集;System.out.println(e)只调用toString(),无堆栈信息。
直接用 e.printStackTrace() 最快,但生产环境必须改用 logger.error("msg", e) —— 否则堆栈会丢在控制台,日志系统根本收不到。
为什么 System.out.println(e) 只显示一行?
它只调用 Throwable.toString(),输出类似 java.lang.NullPointerException: null,不包含任何栈帧信息。调试时完全没用。
- 真正要的是完整调用链:从抛出点 → 方法调用路径 → 每一层的类名、方法名、行号
-
e.printStackTrace()把这些全打到System.err,肉眼可读,适合本地快速验证 - 但它的输出不可捕获、不可重定向、不走日志框架,线上等于“静默失败”
printStackTrace() 的三个重载怎么选?
本质是控制输出目标,不是功能差异:
-
e.printStackTrace()→ 默认输出到System.err -
e.printStackTrace(System.out)→ 强制输出到标准输出(某些容器或 IDE 控制台对err有特殊处理,可能刷屏或被过滤) -
e.printStackTrace(new PrintWriter(stringWriter))→ 写入内存字符串,用于记录、上报或拼装自定义错误响应(比如 REST API 返回带堆栈的 debug info,仅限开发环境)
Logback/Log4j 里正确记录异常的写法
必须把异常对象作为独立参数传给日志方法,不能拼在字符串里: