学会这五个 Python 日志记录技巧,线上排障再也不用慌慌张张了.
做后端开发的朋友,都经历过线上出Bug的焦虑。项目跑着跑着,突然某个接口返回500。你慌了,打开服务器日志,发现满屏都是print打印的普通信息。你想知道具体哪个参数传错了,哪行代码抛了异常,全是一团浆糊。
别慌,用好Python自带的logging模块,能帮你省下大把排查时间。分享五个我踩过坑之后总结的技巧。
1. 别再用print,用logging
很多人图省事,代码里到处是print。开发时看得挺美,一上线就废了。print默认输出到控制台,线上后台服务根本看不到。而且print不能控制级别,紧急错误和普通调试混在一起。
用一句 import logging 替换掉print。 logging.error('请求参数为空') 和 logging.info('用户登录成功') 一目了然。你只要在配置文件里设好级别,线上只打印WARNING及以上,低频日志就干净了。
2. 记录关键变量的上下文
有个同事排查接口超时,日志只写了“处理数据失败”。没人知道失败时传进来的是什么参数。我们只能去求前端帮忙复现,折腾半天。
给日志加上上下文。 比如 logging.error(f'用户{user_id}的订单{order_id}处理失败,错误原因{e}')。错误信息里带上id、名称、状态等关键数据。线上看到这类日志,你不需要问别人,自己就能定位到是哪条数据出了问题。
3. 使用异常堆栈,别只写个提示
我在一段列表操作代码里写了try...except。捕获到异常后,只打印了“列表索引越界”。但具体是哪个列表,哪儿的索引,完全没信息。
logging.exception() 是个宝藏。它能将当前异常发生的完整堆栈信息打印出来。你直接在except块里写 logging.exception('处理列表时出问题'),文件路径、行号、错误信息全有了。再也不用打印一遍str(e)。
4. 把日志按天分割,防止文件过大
曾经我负责过一个小应用,开始日志全写在一个文件里。三个月后,单文件超过5G。用vim打开,直接卡死。查个错误,得用grep慢慢搜,效率极低。
用 TimedRotatingFileHandler。配置成“按天分割”或者“按小时分割”。 每天自动生成一个新日志文件,文件名带日期。 查昨天的问题,只打开昨天的文件。还能设置保留最近30天,旧的自动删除,不占磁盘。
5. 用专属Logger隔离模块日志
同一个项目跑着多个模块,比如支付模块和用户模块。所有日志都打印到同一个地方。支付出错了,你满屏找,看到了大量用户模块的info日志。乱得像菜市场。
给每个模块建一个专属Logger。 payment_logger = logging.getLogger('payment')。每个Logger可以设置不同的文件、不同的格式。你可以在支付模块的日志里只关注支付错误。甚至可以给支付模块设置更高的日志级别,只记录错误,普通用户模块保持info。排查时直奔主题。
这五个技巧落地很快。从明天起,把你项目里的print全部替换掉。线上再出Bug,你打开日志,看到的是清晰的上下文和完整的堆栈。紧张感会消失。