温馨提示×

Ubuntu Python日志管理怎么实现

小樊
39
2025-12-28 07:02:59
栏目: 编程语言

Ubuntu Python日志管理实战指南

一 基础与快速上手

  • 使用标准库 logging 完成控制台与文件输出、分级与格式化,适合绝大多数场景。
  • 示例(同时输出到控制台与文件,按大小轮转):
import logging
from logging.handlers import RotatingFileHandler

# 创建记录器
logger = logging.getLogger("myapp")
logger.setLevel(logging.DEBUG)

# 控制台处理器
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
ch.setFormatter(logging.Formatter("%(levelname)s - %(name)s - %(message)s"))

# 文件处理器(按大小轮转:10MB,保留5个备份)
fh = RotatingFileHandler("app.log", maxBytes=10*1024*1024, backupCount=5)
fh.setLevel(logging.DEBUG)
fh.setFormatter(logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s"))

logger.addHandler(ch)
logger.addHandler(fh)

logger.debug("调试信息")
logger.info("服务启动")
logger.error("发生错误", exc_info=True)  # 记录堆栈
  • 要点:开发环境可用 DEBUG,生产建议 INFO/WARNING;异常务必使用 exc_info=True 保留堆栈。

二 配置分离与多环境管理

  • 使用 dictConfig 将日志配置抽离到 JSON/YAML/INI,便于不同环境快速切换。
  • 示例(JSON 配置,控制台+按天轮转文件):
# config.json
{
  "version": 1,
  "disable_existing_loggers": false,
  "formatters": {
    "simple": {"format": "%(levelname)s - %(message)s"},
    "detailed": {"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"}
  },
  "handlers": {
    "console": {
      "class": "logging.StreamHandler",
      "level": "DEBUG",
      "formatter": "simple",
      "stream": "ext://sys.stdout"
    },
    "timed_file": {
      "class": "logging.handlers.TimedRotatingFileHandler",
      "level": "INFO",
      "formatter": "detailed",
      "filename": "app.log",
      "when": "midnight",
      "interval": 1,
      "backupCount": 7
    }
  },
  "root": {
    "level": "DEBUG",
    "handlers": ["console", "timed_file"]
  }
}
# 加载配置
import logging.config, json
with open("config.json", "r") as f:
    logging.config.dictConfig(json.load(f))
logger = logging.getLogger(__name__)
  • 提示:生产可将轮转策略改为 RotatingFileHandler 控制单文件大小,或保留 TimedRotatingFileHandler 做按天归档。

三 系统级集成与轮转

  • 使用 logrotate 做系统级轮转、压缩与清理(适合长期运行服务与多进程/多实例)。
  • 配置示例(/etc/logrotate.d/python_app):
/var/log/python/*.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
    copytruncate
}
  • 测试与生效:
sudo logrotate -f /etc/logrotate.d/python_app
  • 说明:copytruncate 可在不重启应用的情况下清空原日志文件;若应用支持信号重开日志文件,也可改用 postrotate 发送信号。
  • 可选:将日志写入 systemd journal 并通过 journalctl 查询:
import syslog
syslog.syslog(syslog.LOG_INFO, "来自Python应用的日志")
# 查看:journalctl -f -t python_app
  • 远程集中:通过 rsyslog 转发到日志服务器(UDP/TCP),便于统一采集与审计。

四 第三方与进阶实践

  • Loguru:更简洁的 API,内置轮转、压缩、彩色输出等。
from loguru import logger
logger.add("app.log", rotation="500 MB", retention=5, compression="zip")
logger.info("Hello from Loguru")
  • Sentry:实时错误监控与告警(将 ERROR 及以上上报到云端)。
import sentry_sdk
from sentry_sdk.integrations.logging import LoggingIntegration
sentry_sdk.init(
    dsn="YOUR_DSN",
    integrations=[LoggingIntegration(level=logging.ERROR, event_level=logging.ERROR)]
)
logger = logging.getLogger(__name__)
try:
    1/0
except Exception:
    logger.exception("除零错误")
  • 异步日志:使用 QueueHandler + QueueListener 减少 I/O 阻塞,提高高并发场景性能。
import logging, queue
from logging.handlers import QueueHandler, QueueListener

log_q = queue.Queue(-1)
qh = QueueHandler(log_q)
listener = QueueListener(log_q, logging.FileHandler("async.log"), logging.StreamHandler())
listener.start()

logger = logging.getLogger("async")
logger.addHandler(qh)
logger.setLevel(logging.DEBUG)

# ... 业务代码
# 程序退出前:listener.stop()
  • 建议:在 main 入口统一初始化日志;按模块使用 name 命名记录器;避免重复添加处理器。

五 生产落地清单

  • 目录与权限:将日志写入 /var/log/your_app/,设置合适的 0640 权限与属主(如 root:adm),便于系统工具采集。
  • 日志保留与轮转:按业务与磁盘容量设置 rotate 7~30compress;短任务可用 TimedRotatingFileHandler,长驻进程优先 logrotate
  • 级别与格式:生产用 INFO/WARNING;格式包含 asctime、levelname、name、message,异常务必 exc_info=True
  • 结构化与检索:关键业务可输出 JSON 日志,便于 ELKLoki 检索分析。
  • 监控告警:对接 Sentry 等平台捕获异常;对 ERROR 级别设置告警策略。
  • 高并发:采用 异步日志;必要时按模块拆分日志文件,降低单文件写入竞争。

0