Python 脚本日志怎么分级落盘?排错时一次找准现场

跑一批本地 CLI / 定时脚本时,最烦的不是报错本身,而是:终端刷屏后现场没了,或者多进程一起写,日志串成一团,排错只能靠猜。下面这套做法只解决一件事:日志怎么分级、怎么落盘、排错时怎么一次对齐到某次运行。

先定四级,再谈写文件

级别只保留四个,数字越大越「重」:

级别 数值 适合写什么
debug 10 入参、中间态、分支判断,本地排错开
info 20 正常里程碑:开始、跳过、完成
warn 30 还能继续,但结果可能打折
error 40 失败、未捕获异常、需要人介入

过滤规则很直接:当前阈值阈值,低于阈值的调用直接 return,不打印也不写盘。默认开到 debug,本地脚本库通常宁可多记一点;上线或定时任务再收紧。

用配置改默认级别,别改业务代码

仓库根放一份 env.toml,例如:

toml 复制代码
[logger]
level = "info"

读配置时把 warning 归一成 warn;缺文件、段写错、值非法,一律回落到 debug。单次运行也能在构造时传入 level=,盖过配置,方便「只这一次开全量」。

业务里怎么选级别

  • 成功路径的关键节点:info
  • 可恢复的降级(重试、跳过某步):warn
  • 失败与堆栈:error / exception
  • 只有你坐在机器前才需要看的细节:debug

别把大段二进制、密钥、Cookie 打进日志;需要核对身份时只打脱敏后的短标识。

落盘约定:一天一个文件,一行一条现场

路径固定成项目根下的 logs/<YYYY-MM-DD>_run.log追加不覆盖。同一天多次运行、多个脚本,都往同一个日文件里写,靠行内字段区分,而不是一天拆出几十个小文件。

项目根怎么找:从当前工作目录(或脚本路径)向上走,碰到带 pyproject.toml 的目录就停 。不靠 .git、不靠硬编码 ../..,换机器、换启动 cwd 也不容易写飞。

推荐用法是上下文管理器,保证异常路径也走同一套记录逻辑:

python 复制代码
from core.logger import Logger

with Logger("sync-job") as log:
    log.info("[OK] 开始同步")
    log.debug(f"batch_size={batch_size}")
    # ...
    log.info("[OK] 同步完成")

标准行长什么样

每一行(毫秒时间 | 任务编号 | 级别 | 脚本相对路径 | 正文):

text 复制代码
14:32:08.127 | 8F3K2A9B1C | INFO | cron/jobs/sync.py | [OK] 开始同步
  • 时间HH:mm:ss.SSS,对齐同秒内的先后
  • 任务编号 :一次 Logger 实例一个雪花 ID;同一次运行里所有行共享,grep 它就能抽出完整时间线
  • 级别:大写,方便肉眼扫
  • 脚本路径:相对项目根的 POSIX 路径,多脚本共写一日志时一眼知道是谁打的

终端和文件写同一行内容:print(..., flush=True) 同步刷屏,文件侧再追加。排错时「刚才终端闪过的那行」和磁盘上的行是同一格式。

多进程追加怎么不丢、不乱

多个进程往同一个日文件追加时,用跨进程排他锁(例如 portalocker)包住「打开 → 写入 → flush」。等锁设上限(实现里常见是数秒级);超时后仍尝试无锁追加一次,优先保证「终端已经打出的行」尽量落盘,而不是为了锁干净直接丢行。写完即释放,别把锁拖到整个任务结束。

还有一个容易忽略的细节:子进程 / 子任务如果已经按同一标准格式打过日志,父进程再包一层前缀会变成「日志套日志」。判断「看起来已经是标准行」时,只再打印到终端,不再二次写盘、不再套前缀

排错:用任务编号对齐一次运行

出问题后不要从文件头开始读。先拿终端里任意一行的任务编号,再:

bash 复制代码
rg "8F3K2A9B1C" logs/2026-09-03_run.log

同一编号下,按时间顺序就是那次运行的完整轨迹。需要按脚本收窄时,再叠加路径片段过滤。

异常要把堆栈写进同一次任务

python 复制代码
try:
    do_work()
except Exception as exc:
    log.exception("同步失败", exc)
    raise

exception 先打一条 error 说明,再把堆栈按行写出;续行带 | 前缀,和正文区分开,但仍挂在同一个任务编号下。事后 grep 编号,原因和栈在一起,不用再翻别的 dump。

with Logger(...) 时,未捕获异常会在退出上下文时再记一条;KeyboardInterrupt / SystemExit 不当作故障去刷「未捕获异常」------用户 Ctrl+C 是正常中止,CLI 侧通常只留一行 [SKIP] 已中断 并以退出码 130 结束即可。

落地时的几条硬约束

  1. 统一入口 :业务只走同一个 Logger,别再 print 一套、logging 再一套。
  2. 状态词固定 :成功 / 跳过 / 失败用 [OK] / [SKIP] / [FAIL] / [ERROR],和级别配合,扫日志更快。
  3. 资源与日志无关但也要收尾:进程退出前关掉浏览器、子进程、文件句柄;日志只能告诉你「死在哪」,清不掉孤儿进程。
  4. 日志目录当运行时数据logs/ 不要当源码提交;需要留证时按天拷走即可。

按这套约定,分级决定「记多少」,日文件 + 标准行决定「存在哪、长什么样」,任务编号决定「怎么一次捞齐现场」。下次脚本又挂在半路,先复制编号,再打开当天的 *_run.log

相关推荐
baopixiaoz1 小时前
BeeQuant × BeeAgent:AI量化新范式
大数据·人工智能·python·区块链
IT毕设实战小研1 小时前
基于大数据的AI应用对就业与收入增长的区域差异分析及可视化
大数据·人工智能·python·随机森林·机器学习·课程设计
摆烂老大1 小时前
论文学习 | Expert Systems With Applications2026 | 可微分建模:S4D-HBV
python·学习·水文
程序员夏洛2 小时前
谈谈你了解的最常见的几种设计模式,说说他们的应用场景
开发语言·python·模板方法模式
橙露2 小时前
Cloudflare Pages 深度评测:免费静态托管的香与坑
python·部署
lk123062 小时前
【无标题】
pytorch·python
数据开发 Yang 同学2 小时前
【Python 并发编程】线程、进程、协程、同步/异步一次说清
python
程序员杰哥2 小时前
如何做接口测试?
自动化测试·python·测试工具·职场和发展·测试用例·接口测试·postman
weixin199701080162 小时前
[特殊字符]《从0到1:闲鱼开放平台授权登录 + AccessToken 刷新 + 聚石塔部署完整链路》(附Python源码)
java·数据库·python