Debian上Python日志管理实践
一 基础配置与多处理器输出
import logging
LOG_FMT = '%(asctime)s [%(levelname)s] %(name)s.%(funcName)s:%(lineno)d - %(message)s'
LOG_DATEFMT = '%Y-%m-%d %H:%M:%S'
logging.basicConfig(
level=logging.DEBUG,
format=LOG_FMT,
datefmt=LOG_DATEFMT,
handlers=[
logging.FileHandler('app.log', encoding='utf-8'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
logger.debug('调试信息')
logger.info('服务启动')
二 日志轮转与保留策略
from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler
# 按大小轮转
size_handler = RotatingFileHandler('app.log', maxBytes=10*1024*1024, backupCount=5, encoding='utf-8')
size_handler.setFormatter(logging.Formatter(LOG_FMT, LOG_DATEFMT))
# 按时间轮转
time_handler = TimedRotatingFileHandler(
'app_time.log', when='midnight', interval=1, backupCount=30, encoding='utf-8'
)
time_handler.setFormatter(logging.Formatter(LOG_FMT, LOG_DATEFMT))
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(size_handler)
logger.addHandler(time_handler)
三 系统日志与 journald 集成
import logging
from logging.handlers import SysLogHandler
logger = logging.getLogger('myapp')
logger.setLevel(logging.INFO)
sys_handler = SysLogHandler(address='/dev/log', facility=SysLogHandler.LOG_LOCAL0)
sys_handler.setFormatter(logging.Formatter('%(name)s[%(process)d]: %(message)s'))
logger.addHandler(sys_handler)
logger.info('通过 syslog 写入')
# 查看全部日志
journalctl
# 按服务查看
journalctl -u myapp.service
# 按时间范围查看
journalctl --since "2025-01-01" --until "2025-01-31"
# /etc/logrotate.d/myapp
/var/log/myapp.log {
weekly
rotate 8
compress
delaycompress
missingok
notifempty
}
四 配置管理与最佳实践
# dictConfig 示例
import logging.config
LOG_CFG = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'default': {'format': LOG_FMT, 'datefmt': LOG_DATEFMT},
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'level': 'INFO',
'formatter': 'default',
},
'file': {
'class': 'logging.handlers.TimedRotatingFileHandler',
'level': 'DEBUG',
'formatter': 'default',
'when': 'D', 'interval': 1, 'backupCount': 30,
'filename': 'app.log', 'encoding': 'utf-8',
},
},
'loggers': {
'': {'handlers': ['console', 'file'], 'level': 'DEBUG', 'propagate': True},
},
}
logging.config.dictConfig(LOG_CFG)
logger = logging.getLogger(__name__)
# fileConfig 示例:logging.conf
[loggers]
keys=root,myapp
[handlers]
keys=consoleHandler,fileHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler
[logger_myapp]
level=DEBUG
handlers=fileHandler
qualname=myapp
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=INFO
formatter=simpleFormatter
args=(sys.stdout,)
[handler_fileHandler]
class=handlers.TimedRotatingFileHandler
level=DEBUG
formatter=simpleFormatter
args=('app.log', 'a', 1, 30)
kwargs={'when':'D', 'backupCount':30, 'encoding':'utf-8'}
[formatter_simpleFormatter]
format=%(asctime)s [%(levelname)s] %(name)s.%(funcName)s:%(lineno)d - %(message)s
datefmt=%Y-%m-%d %H:%M:%S
# YAML 示例(需 PyYAML)
version: 1
disable_existing_loggers: false
formatters:
default:
format: '%(asctime)s [%(levelname)s] %(name)s.%(funcName)s:%(lineno)d - %(message)s'
datefmt: '%Y-%m-%d %H:%M:%S'
handlers:
console:
class: logging.StreamHandler
level: INFO
formatter: default
file:
class: logging.handlers.TimedRotatingFileHandler
level: DEBUG
formatter: default
when: D
interval: 1
backupCount: 30
filename: app.log
encoding: utf-8
loggers:
'':
handlers: [console, file]
level: DEBUG
propagate: true