import os
import logging
from logging.handlers import RotatingFileHandler
logger = logging.getLogger(__name__)
class SafeRotatingFileHandler(RotatingFileHandler):
"""安全的日志轮转处理器"""
ACTIVE_FILE_MODE = 0o640
ROTATED_FILE_MODE = 0o440
DIRECTORY_MODE = 0o750
def __init__(self, filename, **kwargs):
filename = str(filename)
log_dir = os.path.dirname(filename)
if log_dir:
os.makedirs(log_dir, mode=self.DIRECTORY_MODE, exist_ok=True)
try:
os.chmod(log_dir, self.DIRECTORY_MODE)
except PermissionError:
logger.warning("Unable to set log directory permissions: %s", log_dir)
pass
kwargs.setdefault('delay', True)
super().__init__(filename, **kwargs)
def doRollover(self):
"""执行轮转并设置所有相关文件权限"""
super().doRollover()
if self.backupCount > 0:
for i in range(1, self.backupCount + 1):
rotated_file = f"{self.baseFilename}.{i}"
if os.path.exists(rotated_file):
self._chmod(rotated_file, self.ROTATED_FILE_MODE)
if os.path.exists(self.baseFilename):
self._chmod(self.baseFilename, self.ACTIVE_FILE_MODE)
def _chmod(self, path, mode):
"""权限设置,文件不存在时静默跳过"""
try:
os.chmod(path, mode)
except (FileNotFoundError, PermissionError):
logger.warning("Unable to set log file permissions: %s", path)
pass
def _open(self):
"""打开文件并设置权限"""
stream = super()._open()
self._chmod(self.baseFilename, self.ACTIVE_FILE_MODE)
return stream