Django 中的 Python 日志记录

标签 python django logging

我正在开发一个 Django 应用程序,并且我正在尝试使用 Python 的日志记录模块进行错误/跟踪日志记录。理想情况下,我希望为站点的不同区域配置不同的记录器。到目前为止,我已经完成了所有这些工作,但有一件事让我摸不着头脑。

我将根记录器转到 sys.stderr,并且我已经配置了另一个记录器来写入文件。这是在我的 settings.py 文件中:

sviewlog = logging.getLogger('MyApp.views.scans')
view_log_handler = logging.FileHandler('C:\\MyApp\\logs\\scan_log.log')
view_log_handler.setLevel(logging.INFO)
view_log_handler.setFormatter(logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s'))
sviewlog.addHandler(view_log_handler)

看起来很简单。但是,问题出在:我写到 sviewlog 的任何内容都会被写入日志文件两次。根记录器只打印一次。就像 addHandler() 被调用了两次。当我将代码通过调试器时,这正是我所看到的。 settings.py 中的代码被执行了两次,因此创建了两个 FileHandler 并将其添加到同一个记录器实例中。但为什么?我该如何解决这个问题?

谁能告诉我这里发生了什么?我已经尝试将 sviewlog 记录器/处理程序实例化代码移动到使用它的文件中(因为这对我来说实际上似乎是合适的位置),但我在那里遇到了同样的问题。我在网上看到的大多数例子都只使用了根记录器,我更喜欢有多个记录器。

最佳答案

请允许我回答我自己的问题。这里的根本问题是 settings.py 被导入两次,甚至更多(参见 here)。 (我仍然不明白为什么会这样。也许一些 Django 专家可以向我解释。)其他一些模块似乎也是如此。在这一点上,我认为假设 settings.py 将被导入多少次是不明智的。就此而言,这样的假设通常是不安全的。我在settings.py以外的地方有过这段代码,结果也差不多。

您必须围绕此编写代码。也就是说,您必须在向其添加其他处理程序之前检查您的记录器是否存在现有处理程序。这有点难看,因为将多个处理程序(即使是同一类型)附加到一个记录器是完全合理的。有一些解决方案可以解决这个问题。一种是检查 logger 对象的 handlers 属性。如果您只想要一个处理程序并且您的长度 > 0,则不要添加它。就我个人而言,我不喜欢这个解决方案,因为它会因为更多的处理程序而变得困惑。

我更喜欢这样的东西(感谢 Thomas Guettler):

# file logconfig.py
if not hasattr(logging, "set_up_done"):
    logging.set_up_done=False

def set_up(myhome):
    if logging.set_up_done:
        return
    # set up your logging here
    # ...
    logging.set_up_done=True

我必须说,我希望 Django 多次导入 settings.py 的事实得到更好的记录。而且我会想象我的配置以某种方式导致了这种多次导入,但是我无法找出导致问题的原因和原因。也许我只是在他们的文档中找不到这一点,但我认为这是你需要警告用户的事情。

关于Django 中的 Python 日志记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/342434/

相关文章:

django - 使用 get_queryset() 方法或设置查询集变量?

Django 管理员过滤用户

python - 静态文件配置不当

logging - RSpec:如何测试 Rails 记录器消息期望?

python - 使用python以循环方式裁剪图像

python - 未使用 .xs() 和 .get_level_values() 在切片上设置值

python - 如何在Nuke中通过Python创建无框架的自定义面板?

java - 在 xml 日志文件中记录 xml 数据

jvm - 是否可以指定 JVM 故障转储的位置?

python - 将特定值中的值替换为相应的值