没有找到与日志记录器相对应的处理程序

21

我是Django的新手。现在我正在尝试Django日志记录。 在尝试时,我遇到了这个错误["No handlers could be found for logger "sample" "].. 这是我的代码:

(在我的settings.py文件中)

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'simple': {
            'format': '%(asctime)s %(levelname)s %(name)s %(message)s'
        },
    },
    'handlers': {
        'default': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': '/home/linuxuser/mani/f/logs/msg.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'simple',
        },
    },
    'loggers': {
        'sample': {
            'handlers': ['default'],
            'level': 'DEBUG',
            'propagate': True,
        },
    }
}

(在我的views.py中)

import logging
import logging.handlers
from django.conf import settings
logger = logging.getLogger('sample')

def empdel(request,id):
    e = get_object_or_404(emp, pk=id)
    e.delete()
    logger.info('A row is deleted successfully !!!')
    return HttpResponseRedirect('/empthanks/')

运行这段代码时,我遇到了这个错误:["No handlers could be found for logger "sample" "]。我的代码有什么问题?即使我在LOGGING中使用了handler,为什么会出现这样的错误?我还试图将日志消息保存到我在LOGGING中使用的文件中...有任何想法吗?提前致谢!!!


1
这段代码对我有效(我更改了文件名)。你能从Django的shell中获取日志记录器吗?你尝试重新启动runserver了吗? - sneeu
@sneeu:是的,现在它可以工作了。我之前使用的是django 1.2.3,所以它无法工作。现在我已经升级到django 1.3,因此现在它可以工作了。还有一个疑问?它会将我的日志消息(我在代码中使用的内容)和一些默认消息保存到该文件中。例如:DEBUG django.db.backends (0.049) 一些SQL查询..为什么会发生这种情况?有什么想法吗? - Mani
Django有一些自己的记录器,看起来是开启的,我建议查看文档。 - sneeu
如果有人在这里寻找此内容,请注意:https://dev59.com/vFcP5IYBdhLWcg3wkKzU - qwerty
2个回答

23

关于这一点文档写得不太清楚,但是当你使用内置的功能来指定日志设置时,你不需要获取一个logger实例。

你只需要执行以下操作:

import logging

def empdel(request,id):
    e = get_object_or_404(emp, pk=id)
    e.delete()
    logging.info('A row is deleted successfully !!!')
    return HttpResponseRedirect('/empthanks/')

10
我认为你有些混淆了。通过在“logging”中调用模块级别的函数,使用的是根记录器。你的例子类似于“import logging”,“logger = logging.getLogger()”,“logger.info(...)”。 - glarrain

13

logging包的上下文中,我认为你误解了Handler的含义。

Handler是一个附加到Logger的对象。每当logger有消息需要处理时,它会将消息发送到其所有handlers。此外,Loggers存在于树结构中,其中名为“root”的Logger位于其根部。在将消息发送给其Handlers后,Logger可能会将其传递给树中的父Logger(由Logger实例的propagate属性确定)。

稍微有趣的是,我曾经发现一个应用程序错误,其中某人开始使用名为“root”的Logger,这与Root Logger不同。

不要使用根Logger(通过logging.info和其他方法或logging.getLogger()访问)。您添加的任何handlers或更改的设置也将影响良好行为的库,这些库将其错误向上传播到根Logger。举个例子:我曾经因懒惰而编写了一个使用根Logger的简单脚本。然后我合并了一些对boto的调用,并得到了大量被传播到根Logger的调试消息。建议您始终创建名称与命名空间中包名称相匹配的Logger(这还可以通过getLogger解释.的方式形成良好的继承结构)通过使用logging.getLogger(__name__)创建logger。

我强烈建议您仔细阅读logging文档中关于Logger对象的部分: https://docs.python.org/2/library/logging.html

您可能会注意到,您的配置还指定了一个Formatter。当处理程序处理消息时,格式化程序处理消息的呈现方式,以便单个消息可以针对终端输出与rsyslog等不同的情况进行格式化。


所有这些说完,为了修复您的代码,您可以使用已创建的logger并向其附加handler。我建议创建一个StreamHandler(基类Handler不是用于实例化的,但由于可怕的原因,它不是ABC),因为它涵盖了许多典型用例。

myhandler = logging.StreamHandler()  # writes to stderr
myformatter = logging.Formatter(fmt='%(levelname)s: %(message)s')
myhandler.setFormatter(myformatter)
logger.addHandler(myhandler)

不过,看起来Django配置已经包含了许多这方面的信息,当然,并不是像我上面所做的那样进行配置。 由于我实际上没有编写过Django应用程序,所以我不想在这方面给你错误的信息,但是Django在这里提供了很好的文档:https://docs.djangoproject.com/en/dev/topics/logging/


什么可怕的原因? - n611x007
1
@naxa 我不完全记得我当时的想法,但可能只是对Python历史上对ABC的反感感到遗憾。长期以来,人们普遍认为,一个不能被实例化的类的概念是不必要的,因为你可以使用鸭子类型。论点是你不应该需要定义基类,只需实现其协议。自2002年首次添加logging以来,这种态度已经发生了变化,并且在2007年添加了ABCs,正是因为像基本Handler类这样的情况。 - sirosen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接