当前位置:  开发笔记 > 编程语言 > 正文

Django中的Python日志记录

如何解决《Django中的Python日志记录》经验,为你挑选了5个好方法。

我正在开发一个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并将其添加到同一个logger实例中.但为什么?我该如何解决这个问题呢?

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



1> Jeff..:

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

你必须围绕这个编码.也就是说,在向其添加其他处理程序之前,您必须检查记录器中的现有处理程序.这有点难看,因为将多个处理程序(即使是相同类型)连接到一个记录器是完全合理的.有一些解决方案可以解决这个问题.一个是检查记录器对象的处理程序属性.如果您只需要一个处理程序且长度> 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专家,但我想每次加载模块时都会导入settings.py,其中包含一个带有"settings"的import语句.使用settings.py的模块越多,导入的次数就越多.
@HartleyBrody [python caches modules](http://docs.python.org/release/2.6/reference/simple_stmts.html#the-import-statement)在加载时,所以通常给定的模块只执行一次,无论如何它出现的import语句数量.

2> Tobu..:

从版本1.3开始,Django使用标准的python日志记录,配置了LOGGING设置(此处记录:1.3,dev).

Django日志参考:1.3,dev.



3> Philippe F..:

很难对您的具体案例发表评论.如果settings.py执行两次,那么每发送一次日志就会得到两行是正常的.

我们遇到了同样的问题,所以我们在项目中设置了一个专门用于记录的模块.那些模块有一个"模块单例"模式,所以我们只执行一次有趣的代码.

它看起来像这样:

def init_logging():
    stdoutHandler = logging.StreamHandler( sys.stdout )
    stdoutHandler.setLevel( DEBUG )
    stdoutHandler.setFormatter( logging.Formatter( LOG_FORMAT_WITH_TIME ) )
    logging.getLogger( LOG_AREA1 ).addHandler( stdoutHandler )

logInitDone=False #global variable controlling the singleton.
if not logInitDone:
    logInitDone = True
    init_logging()

首次导入log.py将正确配置日志记录.



4> A Lee..:

恢复旧线程,但在使用dictConfig格式的 Django 1.3 Python日志记录时,我遇到了重复的消息.

disable_existing_loggers摆脱了重复处理/记录的问题多settings.py负载的,但你仍然可以得到重复的日志消息,如果你不指定propagate适当的具体布尔logger.即,确保propagate=False为子记录器设置.例如,

'loggers': {
    'django': {
        'handlers':['null'],
        'propagate': True,
        'level':'INFO',
    },
    'django.request': {
        'handlers': ['console'],
        'level': 'ERROR',
        'propagate': False,
    },
    'project': {
        'handlers': ['console', 'project-log-file'],
        'level': 'DEBUG',
        'propagate': True,
    },
    'project.customapp': {
        'handlers': ['console', 'customapp-log-file'],
        'level': 'DEBUG',
        'propagate': False,
    },
}

在这里project.customapp设置,propagate=False以便它也不会被project记录器捕获.在Django的记录文档都非常出色,一如既往.



5> Matt Brianço..:

回答关于为什么"Django多次导入settings.py"的问题:它没有.

实际上,它确实会被导入两次(跳过第一个代码块以进入它,但如果你有时间则读取一个好的):

http://blog.dscpl.com.au/2010/03/improved-wsgi-script-for-use-with.html

PS-抱歉恢复旧线程.

推荐阅读
mobiledu2402851377
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有