python logging.handlers.RotatingFileHandler 是否允许创建组可写日志文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1407474/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does python logging.handlers.RotatingFileHandler allow creation of a group writable log file?
提问by Cory Engebretson
I'm using the standard python (2.5.2) logging module, specifically the RotatingFileHandler, on a linux system. My application supports both a command-line interface and a web-service interface. I would like to have both write to the same log file. However, when the log file gets rotated, the new file has 644 permissions and is owned by the web server user which prevents the command-line user from writing to it. Can I specify that new log files should be group-writable in the logging configuration or during logging initialization?
我在 linux 系统上使用标准的 python (2.5.2) 日志模块,特别是 RotatingFileHandler。我的应用程序支持命令行界面和网络服务界面。我希望两者都写入同一个日志文件。但是,当日志文件被轮换时,新文件具有 644 权限,并且由 Web 服务器用户拥有,这会阻止命令行用户对其进行写入。我可以在日志配置中或在日志初始化期间指定新日志文件应该是组可写的吗?
I have looked into the 'mode' setting (r/w/a), but it doesn't seem to support any file permissions.
我查看了“模式”设置 (r/w/a),但它似乎不支持任何文件权限。
采纳答案by Cory Engebretson
I resorted to scanning the logging.handlers module and was unable to see any way to specify a different file permissions mode. So, I have a solution now based on extending the RotatingFileHandler as a custom handler. It was fairly painless, once I found some nice references to creating one. The code for the custom handler is below.
我求助于扫描 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)
I also discovered that to reference the custom handler from a logging config file, I had to bind my module to the logging namespace. Simple to do, but annoying.
我还发现要从日志配置文件中引用自定义处理程序,我必须将我的模块绑定到日志命名空间。做起来很简单,但很烦人。
from mynamespace.logging import custom_handlers
logging.custom_handlers = custom_handlers
References I found useful: binding custom handlersand creating custom handlers
回答by rob
Here is a slightly better solution. this overrides the _open method that is used. setting the umask before creating then returning it back to what it was.
这是一个稍微好一点的解决方案。这会覆盖使用的 _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
回答by DennisLi
Here is a simple solution worked fine:
这是一个简单的解决方案,效果很好:
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
回答by gluejar
Here's a complete solution for Django based on rob's solution. in my_module
:
这是基于rob的解决方案的 Django 完整解决方案。在my_module
:
import logging
import logging.handlers
import os
The class=
that happens during the logging configuration is evaluated in the namespace of the logging module, and by default this does not have a binding to handlers. So we have to put it in explicitly before we can extend it. See this SO article
该class=
日志记录配置过程中发生的记录模块的命名空间进行评估,并在默认情况下,这并不有一个结合的处理程序。所以我们必须明确地把它放进去,然后才能扩展它。请参阅此 SO 文章
logging.handlers = logging.handlers
It's this magical incantation that took me forever to find - I couldn't believe it did anything! Finally, Jon's class will load without errors.
正是这个神奇的咒语让我永远找到了 - 我简直不敢相信它做了任何事情!最后,Jon 的类将正确加载。
class GroupWriteRotatingFileHandler(logging.handlers.RotatingFileHandler):
def _open(self):
prevumask = os.umask(0o002)
rtv = logging.handlers.RotatingFileHandler._open(self)
os.umask(prevumask)
return rtv
To use this for Django add the following this in the settings file
要将其用于 Django,请在设置文件中添加以下内容
from my_module import GroupWriteRotatingFileHandler
logging.handlers.GroupWriteRotatingFileHandler = GroupWriteRotatingFileHandler
And then in LOGGING['handlers']['file']
you have
然后在LOGGING['handlers']['file']
你有
'class': 'logging.handlers.GroupWriteRotatingFileHandler'
回答by tobych
James Gardner has written a handler that only rotates files, not creating or deleting them: http://packages.python.org/logrotate/index.html
James Gardner 编写了一个处理程序,它只轮换文件,而不是创建或删除它们:http: //packages.python.org/logrotate/index.html
回答by wcc526
$ chgrp loggroup logdir
$ chmod g+w logdir
$ chmod g+s logdir
$ usermod -a -G loggroup myuser
$ umask 0002
回答by caot
It looks that def _open(self):
worked with umask(0o000)
to get all the permissions of -rw-rw-rw-
.
这看起来是def _open(self):
一起工作umask(0o000)
得到的所有权限-rw-rw-rw-
。
os.chmod(self.baseFilename, 0o0777)
failed with ValueError: Unable to configure handler 'some_handler': [Errno 1] Operation not permitted:
if the log file has ownership of root:root
that's different from running process's, such as testuser
.
os.chmod(self.baseFilename, 0o0777)
与失败ValueError: Unable to configure handler 'some_handler': [Errno 1] Operation not permitted:
如果日志文件具有所有权root:root
这是从正在运行的进程的,如不同的testuser
。
from logging import handlers
import logging
import os
class GroupWriteRotatingFileHandler(handlers.RotatingFileHandler):
def _open(self):
prevumask = os.umask(0o000) # -rw-rw-rw-
rtv = logging.handlers.RotatingFileHandler._open(self)
os.umask(prevumask)
return rtv
LOGGING = {
'handlers': {
'db_handler': {
'level': 'DEBUG',
'class': 'log.GroupWriteRotatingFileHandler',
'filename': PATH_TO_LOGS + '/db.log',
'maxBytes': maxBytes,
'backupCount': backupCount,
'formatter': 'standard',
},
Log files:
日志文件:
logs]# ls -lrt
-rw-rw-rw- 1 root root 71 Apr 1 16:02 db.log
logs]# ls -lrt
total 0
-rw-rw-rw- 1 testuser testuser 0 Apr 1 16:20 db.log