印度机房里用 screen 恢复会话,滚屏日志截断了一半

在孟买那台 4C8G 的 KVM 上跑一个数据补录脚本,Ubuntu 20.04,Python 3.8,输出量不算大,一天大概 1.2G 的 stdout。之前一直用 nohup python backfill.py > run.log 2>&1 &,SSH 断了进程还在,但输出只有落盘之后才能看,想实时盯进度就得 tail。后来换成了 screen,想的是断线之后重新 attach 能直接看历史输出。

做法很简单:

screen -S backfill -L -Logfile /data/logs/backfill.screen.log \
  bash -c 'python backfill.py 2>&1 | tee /data/logs/backfill.run.log'

-L 开日志,-Logfile 指定路径,外层再套一层 tee 保证原始输出不丢。断线后 screen -r backfill 能接回去。

但第一次跑完发现 screen 的日志只有 300 多 M,而 tee 那份是 1.1G。原因在 screen 的默认设置:screen 的滚屏缓冲和日志写入受 defscrollback 和内部 flush 影响,进程退出太快时最后一段没来得及落盘,而且 -L 写入是追加模式但不会跟随子进程的缓冲节奏。另外 screen 默认不会记录被 clear 或者全屏刷新的内容。

我的取舍是:screen 只当“会话保持 + 实时观察”用,不作为日志的可靠来源。真正的日志交给 tee 或者重定向,screen 的 -L 当作辅助。如果确实需要 screen 那份完整,得在 ~/.screenrc 里加:

defscrollback 10000
logfile flush 1

logfile flush 1 是让 screen 每秒刷一次,代价是 IO 会稍微多一点,在印度这种网络和磁盘都不算快的机器上能感觉到。

失效的地方:logfile flush 只影响 screen 自己的缓冲,管不了子进程的 stdio 缓冲;Python 那边如果没加 -u 或者没设 PYTHONUNBUFFERED=1,tee 拿到的也是块缓冲,screen 日志照样会滞后。我踩过一次,脚本跑了 40 分钟,screen 里一直没输出,以为卡死了,其实是 Python 在缓冲。后来统一在启动命令里加 python -u。

还有个边界:screen 会话被 kill -9 或者机器 OOM 杀掉时,-L 那份日志的最后一段基本保不住,别指望它做审计。

你们在印度这边的机器上,长任务是用 screen、tmux 还是直接 systemd-run 加 journal?我最近在想要不要把 screen 这套换成 systemd 的 StandardOutput,但担心 journal 的轮转策略不好控。

0
赞同度 100% · 0 条评论 · 6 阅读

0 条评论

支持 Markdown · 回复会实时推送给对方

还没有评论,写下第一条。