智能制造场景下AI Agent Harness工程的设计与工业级落地
2026/4/9 16:42:26
Python 应用日志管理:自动化按日期分割日志的完整指南(2025-2026 实用版)
目前生产环境中按日期(或按大小+日期)分割日志仍然是最主流、最可靠的做法。下面给出从简单到生产可用的完整方案梯度。
| 方案 | 是否依赖第三方库 | 是否真正“每天一个文件” | 支持压缩旧日志 | 适合场景 | 推荐指数 |
|---|---|---|---|---|---|
| logging + TimedRotatingFileHandler | 否(标准库) | 是(可精确到分钟) | 否(需额外脚本) | 中小型项目、快速上手 | ★★★★☆ |
| logging + TimedRotatingFileHandler + gzip 脚本 | 否 | 是 | 是(延迟压缩) | 大多数中小型线上服务 | ★★★★★ |
| loguru + rotation=“每天” + retention | 是(loguru) | 是 | 是(内置) | 追求简洁、现代风格的项目 | ★★★★☆ |
| structlog + structlog-processors + 自定义 rotator | 是 | 是 | 可配合 | 需要结构化日志 + JSON 的微服务 | ★★★☆☆ |
| 业务层手动 + os.rename / shutil.move | 否 | 是(但代码侵入性强) | 可配合 | 极致控制需求、特殊格式 | ★★☆☆☆ |
# logger.pyimportloggingfromlogging.handlersimportTimedRotatingFileHandlerimportosimportgzipimportshutilfromdatetimeimportdatetime,timedelta LOG_DIR="logs"os.makedirs(LOG_DIR,exist_ok=True)classGzipRotator:def__call__(self,default_name):# 当轮转发生时,把昨天的文件改名 + 压缩yesterday=(datetime.now()-timedelta(days=1)).strftime("%Y-%m-%d")src=f"{default_name}.{yesterday}"dst=f"{src}.gz"ifos.path.exists(src)andnotos.path.exists(dst):withopen(src,'rb')asf_in:withgzip.open(dst,'wb')asf_out:shutil.copyfileobj(f_in,f_out)os.remove(src)# 删除原文件,节省空间# 配置handler=TimedRotatingFileHandler(filename=os.path.join(LOG_DIR,"app.log"),when="midnight",# 每天 00:00 轮转interval=1,backupCount=0,# 不自动删除旧文件(我们自己管)encoding="utf-8")# 关键:自定义轮转后的文件名处理(加 .gz)handler.rotator=GzipRotator()formatter=logging.Formatter('%(asctime)s [%(levelname)s] %(name)s:%(lineno)d - %(message)s',datefmt='%Y-%m-%d %H:%M:%S')handler.setFormatter(formatter)logger=logging.getLogger("myapp")logger.setLevel(logging.INFO)logger.addHandler(handler)# 控制台也输出(开发方便)console=logging.StreamHandler()console.setFormatter(formatter)logger.addHandler(console)使用方式:
fromloggerimportlogger logger.info("用户登录成功",extra={"user_id":12345,"ip":"1.2.3.4"})logger.error("数据库连接失败",exc_info=True)结果文件结构示例:
logs/ ├── app.log ← 今天正在写的 ├── app.log.2025-01-23.gz ← 昨天的,已压缩 ├── app.log.2025-01-22.gz ...# logger.pyfromloguruimportloggerimportsysfromdatetimeimportdatetime# 删除旧的默认 handlerlogger.remove()# 每天一个文件,保留 30 天,超过 500MB 也轮转,旧文件自动压缩logger.add("logs/app_{time:YYYY-MM-DD}.log",rotation="00:00",# 每天 0 点轮转retention="30 days",# 保留 30 天compression="zip",# 或 "gz", "tar.gz"level="INFO",encoding="utf-8",enqueue=True,# 异步写,性能更好backtrace=True,diagnose=True)# 同时输出到控制台(带颜色)logger.add(sys.stdout,format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>",level="DEBUG"ifos.getenv("DEBUG")else"INFO",colorize=True)# 使用(几乎和 print 一样方便)logger.info("用户登录",user_id=12345,ip="1.2.3.4")logger.exception("出错了")# 自动带 tracebackloguru 最大优势:一行配置搞定轮转、压缩、保留、结构化输出。
容器/K8s 环境
logrotate 方案(不改代码)(经典且可靠)
# /etc/logrotate.d/myapp/var/app/logs/app.log{daily rotate30missingok dateext dateformat -%Y-%m-%d compress delaycompress copytruncate# 重要:不重启应用也能切割suappuser appgroup}# loguru JSON 示例logger.add("logs/app_{time:YYYY-MM-DD}.json",format="{time} {level} {message}",serialize=True,# 输出 JSONrotation="00:00",retention="90 days",compression="zip")| 需求 | 推荐方案 | 核心代码行数 |
|---|---|---|
| 最快上手、零配置 | loguru | 8–12 行 |
| 完全不引入第三方包 | TimedRotating + gzip | 25–35 行 |
| 必须 JSON 结构化 + 微服务 | structlog + JSON | 20–40 行 |
| K8s / Docker 不写文件 | stdout + fluentbit | 0 行(业务) |
| 已有 logrotate 基础设施 | 标准 logging + copytruncate | 10 行 |
你当前的项目属于哪种情况?
告诉我你的具体场景,我可以给你最贴合的一份完整配置代码。