找不到日志处理程序

21 投票
2 回答
44126 浏览
提问于 2025-04-16 21:49

我刚开始学习Django,现在在尝试使用Django的日志功能。在这个过程中,我遇到了一个错误,内容是["没有找到处理器来处理日志记录器 "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/')

运行这段代码时,我收到了这个错误,也就是["没有找到处理器来处理日志记录器 "sample" "]。我的代码哪里出问题了呢?为什么即使我在LOGGING中使用了处理器,还是会出现这样的错误?另外,我还想把日志信息保存到我在LOGGING中指定的文件里……有没有什么建议?谢谢大家!!!

2 个回答

13

我觉得你对logging包里的Handler理解得不太对。

简单来说,Handler就是你连接到Logger上的一个对象。每当Logger有消息需要处理时,它会把消息发送给所有的Handler。此外,Loggers是以树状结构存在的,树的根部有一个叫“root”的Logger。在把消息发送给它的Handlers后,Logger还可能把消息传递给它在树中的父节点(这个是由Logger实例的propagate属性决定的)。

顺便说一句,我曾经发现一个应用程序的bug,就是有人开始使用名为“root”的Logger,这和Root Logger是不同的。

不要使用根Logger(通过logging.info等访问,或者logging.getLogger())。你连接的任何Handlers或者修改的设置都会影响那些把错误信息传递到根Logger的库。举个例子:我曾经因为懒惰写了一个简单的脚本,使用了根Logger。结果在调用boto时,收到了大量的调试信息,这些信息被传递到了根Logger。建议你总是创建一个Logger,它的名字和你包的名字一致(这样也能形成不错的继承结构,getLogger会理解.的含义),可以通过logging.getLogger(__name__)来创建。

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

你可能会注意到你的配置中还指定了一个Formatter。Formatter负责处理消息在Handler处理时的展示方式,这样同一条消息在终端输出时和在其他地方(比如rsyslog)输出时可以有不同的格式。


说了这么多,要修复你的代码,你可以使用你创建的logger,然后给它添加一个handler。我建议你创建一个StreamHandler(基础的Handler类不应该被实例化,但出于一些糟糕的原因,它并不是一个抽象基类),因为这能覆盖很多常见的使用场景。

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/

23

文档对这个问题的说明有点模糊,但当你使用内置的功能来设置日志记录时,其实不需要去获取一个日志记录器的实例。

你只需要这样做:

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/')

撰写回答