Django安装程序默认日志记录


94

我似乎无法弄清楚如何为Django安装设置“默认”记录器。我想在中使用Django 1.3的新LOGGING设置settings.py

我看过Django Logging Doc的示例,但在我看来,他们只设置了将为特定记录器记录日志的处理程序。在他们的示例中,他们为名为“ django”,“ django.request”和“ myproject.custom”的记录器设置了处理程序。

我要做的只是设置一个默认值logging.handlers.RotatingFileHandler,它将默认处理所有记录器。即,如果我在项目中的某个地方创建了一个新模块,并用如下符号表示:my_app_name.my_new_module,我应该能够做到这一点,并将所有日志记录转到旋转文件日志中。

# In file './my_app_name/my_new_module.py'
import logging
logger = logging.getLogger('my_app_name.my_new_module')
logger.debug('Hello logs!') # <-- This should get logged to my RotatingFileHandler that I setup in `settings.py`!

Answers:


153

弄清楚了...

您可以使用空字符串引用来设置“全部捕获”记录器''

举例来说,在以下设置中,我将所有日志事件保存到logs/mylog.log,除了django.request日志事件将保存到logs/django_request.log。因为'propagate'设置False为我的django.request记录器,所以日志事件将永远不会到达“全部捕获”记录器。

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        'standard': {
            'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
        },
    },
    'handlers': {
        'default': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': 'logs/mylog.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },  
        'request_handler': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': 'logs/django_request.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },
    },
    'loggers': {
        '': {
            'handlers': ['default'],
            'level': 'DEBUG',
            'propagate': True
        },
        'django.request': {
            'handlers': ['request_handler'],
            'level': 'DEBUG',
            'propagate': False
        },
    }
}

2
克里斯(Chris),关于此的Django文档并不令人困惑。谢谢你

5
微小的修正:该注释暗示sql日志记录将受到django.request记录器的影响。要重定向sql日志记录,您需要为django.db定义一个记录器。django.request记录器处理5xx和4xx http响应。
rych 2011年

这样可以帮助像我这样的其他菜鸟:记录器将创建日志文件,但是您必须先创建logs/文件夹:-)。否则,运行时会出现错误./manange.py runserver。@Chris W.感谢您提供示例日志记录设置。它对我帮助很大!
hobbes3'4

3
@arindamroychowdhury通过上述配置,如果你这样做logger = logging.getLogger('foo'); logger.warn('bar');,则default处理程序将赶上记录之类的东西<time> WARN: foo: bar会在最后logs/mylog.log
克里斯W.

8
谢谢,看来这''表示root记录器。在Django文档中找不到此有用的信息。
EinoMäkitalo13年

25

正如您在回答 Chris中所说,定义默认记录器的一种方法是使用空字符串作为其键。

但是,我认为预期的方法是root在日志记录配置字典的键下定义一个特殊的日志记录器。我在Python文档中找到了这个:

root-这将是root记录器的配置。配置的处理将与所有记录器相同,但该propagate设置将不适用。

这是您的答案更改为使用root键后的配置:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        'standard': {
            'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
        },
    },
    'handlers': {
        'default': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': 'logs/mylog.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },  
        'request_handler': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': 'logs/django_request.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },
    },
    'root': {
        'handlers': ['default'],
        'level': 'DEBUG'
    },
    'loggers': {
        'django.request': {
            'handlers': ['request_handler'],
            'level': 'DEBUG',
            'propagate': False
        },
    }
}

公平地说,我看不到这两种配置在行为上有任何区别。似乎使用空字符串键定义记录器将修改根记录器,因为logging.getLogger('')它将返回根记录器。

我比较喜欢的唯一原因'root'''在于它是明确有关修改根记录。如果您很好奇,请定义两个都'root'覆盖'',这是因为根条目是最后处理的。


是的,没错,很抱歉改错!虽然使用''代替'root'有点逻辑,但我仍然发现root在将2.6 fileConfig逻辑平稳过渡到2.7 dictConfig的过程中,将条目移动到dict的根中有点不一致。
Antony Hatchkins 2014年

2
import logging
logger = logging.getLogger(__name__)

添加后:

logging.basicConfig(
    level = logging.DEBUG,
    format = '%(name)s %(levelname)s %(message)s',
)

我们可以将格式更改为:

format = '"%(levelname)s:%(name)s:%(message)s"  ',

要么

format = '%(name)s %(asctime)s %(levelname)s %(message)s',

0

我做了一个快速示例来检查在config dict中同时引用rootkey和empty ''logger时使用的配置。

import logging.config

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'fmt1': {
            'format': '[FMT1] %(asctime)-15s %(message)s',
        },
        'fmt2': {
            'format': '[FMT2] %(asctime)-15s %(message)s',
        }
    },
    'handlers': {
        'console1': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'fmt1',
        },
        'console2': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'fmt2',
        },
    },
    # First config for root logger: console1 -> fmt1
    'root': {
        'handlers': ['console1'],
        'level': 'DEBUG',
        'propagate': True,
    },
    'loggers': {
        # Second config for root logger: console2 -> fmt2
        '': {
            'handlers': ['console2'],
            'level': 'DEBUG',
            'propagate': True,
        },
    },
}

logging.config.dictConfig(LOGGING)

l1 = logging.getLogger()
l2 = logging.getLogger('')
root = logging.root

l1.info("l1")
l2.info("l2")
root.info("root logger")

打印以下结果:

[FMT1] 2018-12-18 17:24:47,691 l1
[FMT1] 2018-12-18 17:24:47,691 l2
[FMT1] 2018-12-18 17:24:47,691 root logger

表示root密钥下的配置具有最高优先级。如果删除了该块,则结果为:

[FMT2] 2018-12-18 17:25:43,757 l1
[FMT2] 2018-12-18 17:25:43,757 l2
[FMT2] 2018-12-18 17:25:43,757 root logger

在这两种情况下,我能够调试并确定所有三个记录器(l1l2root)引用相同的记录器实例,根记录器。

希望这将对像我一样对配置根记录程序的两种不同方式感到困惑的其他人有所帮助。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.