Ubuntu下Python日志管理实战指南
一 基础配置与多处理器输出
import logging
def setup_logging():
fmt = '%(asctime)s %(levelname)s %(name)s: %(message)s'
datefmt = '%Y-%m-%d %H:%M:%S'
logging.basicConfig(level=logging.DEBUG, format=fmt, datefmt=datefmt)
logger = logging.getLogger()
# 控制台:INFO及以上
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
ch.setFormatter(logging.Formatter(fmt, datefmt))
logger.addHandler(ch)
# 文件:DEBUG及以上
fh = logging.FileHandler('app.log', encoding='utf-8')
fh.setLevel(logging.DEBUG)
fh.setFormatter(logging.Formatter(fmt, datefmt))
logger.addHandler(fh)
return logger
if __name__ == '__main__':
log = setup_logging()
log.debug('调试信息')
log.info('应用启动')
log.warning('磁盘空间不足')
log.error('处理请求失败')
二 日志轮转与清理
应用内轮转:使用 RotatingFileHandler(按大小)或 TimedRotatingFileHandler(按时间)自动切割,适合单进程/多进程写同一日志文件的场景。
系统级轮转:使用 logrotate 管理日志生命周期(压缩、保留、按日/周轮转),适合长期运行服务与系统统一治理。
应用内按大小轮转示例(保留最近 3 个、单文件 1MB):
from logging.handlers import RotatingFileHandler
logger = logging.getLogger(__name__)
handler = RotatingFileHandler('app.log', maxBytes=1*1024*1024, backupCount=3, encoding='utf-8')
handler.setLevel(logging.DEBUG)
handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(name)s: %(message)s'))
logger.addHandler(handler)
sudo nano /etc/logrotate.d/myapp
/var/log/myapp/*.log {
daily
rotate 7
compress
missingok
notifempty
copytruncate
}
sudo logrotate -vf /etc/logrotate.d/myapp
三 结构化日志与集中化采集
import logging
from json_log_formatter import JSONFormatter
logger = logging.getLogger('json')
handler = logging.StreamHandler()
handler.setFormatter(JSONFormatter())
logger.addHandler(handler)
logger.setLevel(logging.INFO)
logger.info('用户登录', extra={'user': 'alice', 'ip': '192.168.1.10'})
四 运行在 systemd 下的实践
[Unit]
Description=My Python App
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/python3 /opt/myapp/app.py
StandardOutput=journal
StandardError=journal
Restart=on-failure
[Install]
WantedBy=multi-user.target
# 实时查看
journalctl -u myapp.service -f
# 结构化查看
journalctl -u myapp.service -o json-pretty
# 按时间范围
journalctl -u myapp.service --since "2025-12-06 00:00:00" --until "2025-12-06 12:00:00"