1

这是我的日志配置settings.py

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
        'file': {
            'class': 'logging.FileHandler',
            'filename': os.path.join(BASE_DIR, 'logs', 'django.log'),
        },
    },
    'loggers': {
        'django': {
            'handlers': ['file', 'console'],
            'level': 'DEBUG',
        },
        'django.template': {
            'handlers': ['file', 'console'],
            'level': 'INFO',
        },
        'App': {
            'handlers': ['file', 'console'],
            'level': 'DEBUG',
        },
    },
}

有一个我无法解释的行为:如果我运行,debug=True我可以看到所有 SQL 查询都记录到控制台,但是当debug=False这种情况没有发生时,即使我没有更改上面的配置。

为什么是这样?如何在我的日志记录配置中确定 SQL 查询是否记录到控制台?

4

2 回答 2

2

随着 Django 根据计算属性的真实性包装数据库游标,查询日志记录变得更深入。

第 226 行开始,django.db.backends.base.base v2.2.6 来源

def _prepare_cursor(self, cursor):
    """
    Validate the connection is usable and perform database cursor wrapping.
    """
    self.validate_thread_sharing()
    if self.queries_logged:
        wrapped_cursor = self.make_debug_cursor(cursor)
    else:
        wrapped_cursor = self.make_cursor(cursor)
    return wrapped_cursor

此计算属性将决定在何处强制调试或在项目设置中启用调试

第 149 行开始,django.db.backends.base.base v2.2.6 来源

@property
def queries_logged(self):
    return self.force_debug_cursor or settings.DEBUG

您应该能够获得默认连接的代理并强制使用调试光标。

from django.db import connection

connection.force_debug_cursor = True

但是,我建议不要使用这种方法,并支持在数据库中进行查询审计。

于 2019-10-15T16:04:34.170 回答
2

那是因为现有的记录器已经过滤了您的日志。在这种情况下是Django 的 logger

DEFAULT_LOGGING = {
    'filters': {
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    'handlers': {
        'console': {
            'level': 'INFO',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
        },
    ...
}

django.utils.log.RequireDebugTrue

class RequireDebugTrue(logging.Filter):
    def filter(self, record):
        return settings.DEBUG

要解决此问题,您可以通过 set 禁用现有记录器, disable_existing_loggers: True也可以像这样覆盖过滤器:

LOGGING = {
    ...
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'filters': [],
        },
    ...
}
于 2019-10-15T14:41:12.587 回答