python logging.handlers.RotatingFileHandler 是否允许创建可组写的日志文件?

40 投票
8 回答
16471 浏览
提问于 2025-04-15 14:13

我在一个Linux系统上使用标准的Python(2.5.2)日志模块,特别是RotatingFileHandler。我的应用程序既有命令行界面,也有网络服务接口。我希望这两者都能写入同一个日志文件。然而,当日志文件被轮换时,新文件的权限是644,而且是由网络服务器的用户拥有,这就导致命令行用户无法写入这个文件。我可以在日志配置中或者在日志初始化时指定新日志文件应该是组可写的吗?

我查看过mode设置(r/w/a),但似乎不支持任何文件权限的设置。

8 个回答

3

这里有一个简单的解决方案,效果很好:

import os

class GroupWriteRotatingFileHandler(handlers.RotatingFileHandler):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        os.chmod(self.baseFilename, 0o0777)  # You can change whatever permission you want here.

        # you can also change the group of the file:
        os.chown(self.baseFilename, uid, gid)   # pass the user_id and group_id you want to set 

33

这里有一个稍微更好的解决方案。这个方法重写了用到的_open方法。在创建之前设置了umask,然后再把它恢复到原来的状态。

class GroupWriteRotatingFileHandler(logging.handlers.RotatingFileHandler):    
    def _open(self):
        prevumask=os.umask(0o002)
        #os.fdopen(os.open('/path/to/file', os.O_WRONLY, 0600))
        rtv=logging.handlers.RotatingFileHandler._open(self)
        os.umask(prevumask)
        return rtv
23

我查看了logging.handlers这个模块,但没找到设置文件权限模式的办法。所以,我现在有了一个解决方案,就是通过扩展RotatingFileHandler来创建一个自定义处理器。这个过程其实挺简单的,找到一些不错的参考资料后就顺利完成了。下面是这个自定义处理器的代码。

class GroupWriteRotatingFileHandler(handlers.RotatingFileHandler):

    def doRollover(self):
        """
        Override base class method to make the new log file group writable.
        """
        # Rotate the file first.
        handlers.RotatingFileHandler.doRollover(self)

        # Add group write to the current permissions.
        currMode = os.stat(self.baseFilename).st_mode
        os.chmod(self.baseFilename, currMode | stat.S_IWGRP)

我还发现,要在日志配置文件中引用这个自定义处理器,我需要把我的模块绑定到日志命名空间。这个操作很简单,但有点麻烦。

from mynamespace.logging import custom_handlers
logging.custom_handlers = custom_handlers

我找到了一些有用的参考资料: 绑定自定义处理器创建自定义处理器

撰写回答