跳到内容

元数据卡

  • 前置知识:第6章·读懂栈调用
  • 预计时间:15 分钟
  • 完成标志:能在项目中配置日志库并写入日志文件

场景:程序半夜崩了

"你的程序昨天半夜崩了,"同事说。"但你睡着了——那你怎么知道发生了什么?"

你愣住了。"我可以在终端里开着程序?"

"那不是办法。"工坊主人摇头。"程序需要自己记录——像航海日志一样,每一件大事小情都写下来。哪怕没人看着,记录也在。"

真正的程序不会把错误只打到你终端上。它们把运行中的一切事件记到日志文件里。

为什么不用 System.out?

System.out.println("到了这里") 停——问题有三:

  1. 只输出到 stdout,不进日志文件,重启就丢
  2. 生产环境没人看 stdout,服务器控制台一闪而过
  3. 没有级别——重要错误和调试信息混在一起

规则:用日志库,永远不用 System.out / print() 来 Debug。

日志级别

标准级别从低到高——越低越详细:

级别什么时候用示例
TRACE极端调试才开循环的每一轮
DEBUG开发阶段信息SQL 语句、API 参数
INFO正常的里程碑事件服务启动、任务完成
WARN不致命但值得关注配置缺失用默认值
ERROR需要人工介入数据库连不上、支付失败

开发时开 DEBUG,生产环境开 INFO,排查时临时把某包降到 DEBUG。

动手:加日志

python
# Python + loguru
# 安装: pip install loguru
# 运行: python3 app.py
from loguru import logger

def forge_item(item_id):
    logger.info("开始锻造工件 #{}", item_id)
    try:
        result = heat_and_hammer(item_id)
        logger.info("工件 #{} 锻造成功", item_id)
        return result
    except Exception as e:
        logger.error("工件 #{} 锻造失败: {}", item_id, e)
        raise
java
// Java + SLF4J / Logback
// pom.xml 加 spring-boot-starter-logging 依赖
// 运行: java -jar target/app.jar
private static final Logger log =
    LoggerFactory.getLogger(ForgeService.class);
log.info("开始锻造工件 {}", id);
log.error("锻造失败", exception);
javascript
// JavaScript + winston
// 安装: npm install winston
// 运行: node app.js
const logger = winston.createLogger({
    level: 'info',
    transports: [
        new winston.transports.Console(),
        new winston.transports.File({ filename: 'app.log' })
    ]
});
logger.info('开始锻造 #%s', itemId);

看日志:grep 过滤

bash
grep "ERROR" application.log
grep "2026-06-23 14:" app.log | grep "ERROR"
grep "工件 #1024" app.log
tail -n 50 application.log  # 最后50行
less application.log        # 分页浏览

为什么加日志比猜 bug 更值

出问题的时候,日志是你唯一的证人。关键路径(启动、请求入口、异常 catch、外部调用)上多花 5 秒写一行 logger.info(),比花半小时猜"到底发生了什么"划算得多。

本讲小结

  • 用日志库替代 System.out.println——日志能写文件、分级、检索
  • 日志级别:TRACE < DEBUG < INFO < WARN < ERROR
  • 善用 greptailless 查看日志
  • 关键路径加日志,出问题翻日志而不是翻代码

下一步:写最小复现

你学会了读栈调用、加日志——但有的 bug 看不懂,需要请教别人。怎么问问题才高效?最小复现是你的终极武器。

第6章:最小复现

Built with VitePress | Software Systems Atlas