美文网首页django
Django DEGUB=False 时,异常和堆栈信息记录

Django DEGUB=False 时,异常和堆栈信息记录

作者: Su_yj | 来源:发表于2020-04-11 23:43 被阅读0次

一直以来都有一个疑惑,django在 DEBUG = True 时,程序出错时会把错误的堆栈信息打印到控制台,然而当 DEBUG = False 时,程序异常只是显示一条状态码为500 的记录,而堆栈信息不会显示。

[11/Apr/2020 23:10:19] "GET /api/v1/course/1/ HTTP/1.1" 500 145

由于服务器上一般用 uwsgi 来部署,所以 uwsgi 拿到的日志即 Django 的控制台输出日志,因此应该只需要修改 Django 控制台输出的日志,uwsgi 就能拿到的异常时的堆栈信息了。

在查看 StackOverflow 的这条问题 How do you log server errors on Django sites 后,发现有两种方法可以实现错误信息的堆栈输出。

方法一:通过中间件处理异常

在项目中创建一个py文件(名字随便),我这里创建在 utils/middleware.py ,并创建一个类通过 process_exception 方法处理异常

# utils/middleware.py
import logging
from django.conf import settings
from django.utils.deprecation import MiddlewareMixin

class ErrorMiddleware(MiddlewareMixin):
    def process_exception(self, request, exception):
        if not settings.DEBUG:
            logging.exception(exception)

settings.py 添加该中间件

# settings.py
DEBUG = False

MIDDLEWARE = [
    ......
    'utils.middleware.ErrorMiddleware',  # 这是你写的类的导入路径
]

方法二:修改 Django 的 log 日志配置

Django 的 log 默认配置如下

# django\utils\log.py

DEFAULT_LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse',
        },
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    'formatters': {
        'django.server': {
            '()': 'django.utils.log.ServerFormatter',
            'format': '[{server_time}] {message}',
            'style': '{',
        }
    },
    'handlers': {
        'console': {
            'level': 'INFO',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
        },
        'django.server': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'django.server',
        },
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        }
    },
    'loggers': {
        'django': {
            'handlers': ['console', 'mail_admins'],
            'level': 'INFO',
        },
        'django.server': {
            'handlers': ['django.server'],
            'level': 'INFO',
            'propagate': False,
        },
    }
}

查看 Django 的 log 配置发现,原来控制台输出的日志时做了过滤,因此最简单的方法就是把 handlersconsolefilters 注释了就可以,因此在 settings.py 文件下添加一下配置:

# settings.py

DEFAULT_LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse',
        },
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    'formatters': {
        'django.server': {
            '()': 'django.utils.log.ServerFormatter',
            'format': '[{server_time}] {message}',
            'style': '{',
        }
    },
    'handlers': {
        'console': {
            'level': 'INFO',
            # 'filters': ['require_debug_true'],  # 把该条件注释,使得debug不管True或False都有效
            'class': 'logging.StreamHandler',
        },
        'django.server': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'django.server',
        },
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        }
    },
    'loggers': {
        'django': {
            'handlers': ['console', 'mail_admins'],
            'level': 'INFO',
        },
        'django.server': {
            'handlers': ['django.server'],
            'level': 'INFO',
            'propagate': False,
        },
    }
}

根据上面的配置,还可以进行自定义,把日志写入到本地,配置如下

# settings.py

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        # Include the default Django email handler for errors
        # This is what you'd get without configuring logging at all.
        'mail_admins': {
            'class': 'django.utils.log.AdminEmailHandler',
            'level': 'ERROR',
             # But the emails are plain text by default - HTML is nicer
            'include_html': True,
        },
        # Log to a text file that can be rotated by logrotate
        'logfile': {
            'class': 'logging.handlers.WatchedFileHandler',
            'filename': '/var/log/django/myapp.log'
        },
    },
    'loggers': {
        # Again, default Django configuration to email unhandled exceptions
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
        # Might as well log any errors anywhere else in Django
        'django': {
            'handlers': ['logfile'],
            'level': 'ERROR',
            'propagate': False,
        },
        # Your own app - this assumes all your logger names start with "myapp."
        'myapp': {
            'handlers': ['logfile'],
            'level': 'WARNING', # Or maybe INFO or DEBUG
            'propagate': False
        },
    },
}

参考:

  1. How do you log server errors on django sites
  2. Django logging 配置
  3. Django 系统日志logging

相关文章

  • Django DEGUB=False 时,异常和堆栈信息记录

    一直以来都有一个疑惑,django在 DEBUG = True 时,程序出错时会把错误的堆栈信息打印到控制台,然而...

  • 异常与调试

    通过try...except...finally处理异常。 调用堆栈 出现异常返回时,会打印调用堆栈 记录错误 抛...

  • jvm参数配置

    核心配置参数:-OmitStackTraceInFastThrow:当大量异常时,jvm默认不打印后面的堆栈信息,...

  • 异常没有堆栈信息

    代码里面使用了System.out.println(e.toString()); e.toString()调用了e...

  • WPF捕获全局未处理异常

    WPF中捕获全局异常并记录 应用有时候会异常崩溃,这时候如果有错误的堆栈信息,就很方便我们查找问题。捕获未处理异常...

  • Django使用Email跟踪代码错误

    Django使用Email跟踪代码错误 运行到服务器上后DEBUG=False,当访问出现异常时,通过邮件发送错误...

  • Django的DEBUG=False

    Django设置DEBUG为False时,'django.contrib.staticfiles'会关闭,即Dja...

  • 二十三、归约问题定位思路

    一、问题描述 开发通过Jone编译部署时,报错如下: 二、问题定位 看异常堆栈是依赖问题,但是异常信息不清晰; 观...

  • 问题排查 java.lang.NoSuchMethodError

    问题背景 代码: 上传文件时,在 doFilter 报错,异常堆栈: 排查流程 google 搜不到任何相关信息,...

  • 异常堆栈输出为字符串

    今天要记录下一个功能,就是将异常信息,通过邮件发送给我。过程中遇到一个问题,怎样获取到异常堆栈信息并将它输出为字符...

网友评论

    本文标题:Django DEGUB=False 时,异常和堆栈信息记录

    本文链接:https://www.haomeiwen.com/subject/zanpmhtx.html