【问题标题】:Log SQL queries even if DEBUG=False即使 DEBUG=False 也记录 SQL 查询
【发布时间】:2019-10-15 14:07:40
【问题描述】:

这是我在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 查询是否记录到控制台?

【问题讨论】:

    标签: django logging python-logging


    【解决方案1】:

    这是因为现有的记录器已经过滤了您的日志。在这种情况下是Django's 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
    

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

    LOGGING = {
        ...
        'handlers': {
            'console': {
                'class': 'logging.StreamHandler',
                'filters': [],
            },
        ...
    }
    

    【讨论】:

      【解决方案2】:

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

      来自Line 226, django.db.backends.base.base v2.2.6 sources

      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
      
      

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

      来自Line 149, django.db.backends.base.base v2.2.6 sources

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

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

      from django.db import connection
      
      connection.force_debug_cursor = True
      

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

      【讨论】:

        猜你喜欢
        • 2011-11-03
        • 2017-03-29
        • 2022-10-17
        • 1970-01-01
        • 1970-01-01
        • 2021-08-13
        • 2021-10-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多