美文网首页
python异常助手之better-exceptions

python异常助手之better-exceptions

作者: python取经小分队 | 来源:发表于2017-10-23 12:44 被阅读245次

简介

better-exceptions 可以在python异常发生时显示更多信息,帮助我们更好的发现问题.

介绍这个库前,我们先看一个简单的例子(example.py),代码如下:

# -*- encoding: utf-8 -*-

def get_student_infos(logs):
    student_infos = []
    for log in logs:
        name, catgory, grade = log.split(' ')
        student_infos.append({
            'name': name,
            'catgory': catgory,
            'grade': grade,

        })
    return student_infos

if __name__ == '__main__':
    exam_logs = [
        'zhangsan math 60',
        'lisi english 80',
        'wangwu chinese 90',
        'qianliu music'
    ]
    get_student_infos(exam_logs)

运行输出:

Traceback (most recent call last):
  File "example.py", line 23, in <module>
    get_student_infos(exam_logs)
  File "example.py", line 7, in get_student_infos
    name, catgory, grade = log.split(' ')
ValueError: not enough values to unpack (expected 3, got 2)

如果我们给example.py增加一行代码import better_exceptions,再执行,输入如下:

Traceback (most recent call last):
  File "example.py", line 24, in <module>
    get_student_infos(exam_logs)
    │                 └ ['zhangsan math 60', 'lisi english 80', 'wangwu chinese 90', 'qianliu music']
    └ <function get_student_infos at 0x7f147344ee18>
  File "example.py", line 8, in get_student_infos
    name, catgory, grade = log.split(' ')
    │     │        │       └ 'qianliu music'
    │     │        └ '90'
    │     └ 'chinese'
    └ 'wangwu'
ValueError: not enough values to unpack (expected 3, got 2)

看到了吗,加上import better_exceptions后, 异常时会将调用栈每一层用的变量值打印出来, 和普通异常时输出有比有什么好处呢,然我们来回忆一下,

  • 没有better_exceptions时是这样对待异常的:
    • 看到一个异常, 能看到异常的类型, 但是无法直接给出错误原因
    • 追踪异常时, 往往得修改代码,将关键变量打印出来. 如果是线上环境, 貌似没什么好办法,只能上线上改一改.
  • better_exceptions时:
    • 从异常时打印出来的信息可以清晰的看到异常发生时变量的值,可很容易定位问题.

是不是有小伙伴会想, 要是某些变量特别大(比如有几万个元素的列表),这样会造成日志很大的.确实存在这样的问题,不过这个库的作者已经够给解决方案了: 加上这句better_exceptions.MAX_LENGTH = 字符数控制字符的个数, 对于上面的例子加上better_exceptions.MAX_LENGTH = 20这句输出如下:

Traceback (most recent call last):
  File "example.py", line 27, in <module>
    get_student_infos(exam_logs)
    │                 └ ['zhangsan math 60',...
    └ <function get_studen...
  File "example.py", line 10, in get_student_infos
    name, catgory, grade = log.split(' ')
    │     │        │       └ 'qianliu music'
    │     │        └ '90'
    │     └ 'chinese'
    └ 'wangwu'
ValueError: not enough values to unpack (expected 3, got 2)

看到了吗,只是简单的再代码上加上一句import better_exceptions就有如此神奇的效果. 但是, 这个库目前只会在控制台打印出这样的错误信息, 下面说一下怎么与logging、django集成.

logging接入

先简单说一下,:

  • logging模块在输出一个异常的时候,会调用handlerformaterformatException函数来格式化异常.
  • better_exceptions有个format_exception方法会将异常调用栈变量值输出,就是 上面例子的那种输出.

看代码:

# -*- encoding: utf-8 -*-
import logging
from better_exceptions import format_exception

logger = logging.getLogger()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
formatter.formatException = lambda exc_info: format_exception(*exc_info)

file_handler = logging.FileHandler("example.log")
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
def get_student_infos(logs):
    student_infos = []
    for log in logs:
        name, catgory, grade = log.split(' ')
        student_infos.append({
            'name': name,
            'catgory': catgory,
            'grade': grade,

        })
    return student_infos

if __name__ == '__main__':
    exam_logs = [
        'zhangsan math 60',
        'lisi english 80',
        'wangwu chinese 90',
        'qianliu music'
    ]
    try:
        get_student_infos(exam_logs)
    except Exception as e:
        logger.exception(e)

查看example.log文件输出:

2017-09-03 22:07:47,121 - root - ERROR - not enough values to unpack (expected 3, got 2)
Traceback (most recent call last):
  File "log_example.py", line 39, in <module>
    get_student_infos(exam_logs)
    │                 └ ['zhangsan math 60', 'lisi english 80', 'wangwu chinese 90', 'qianliu music']
    └ <function get_student_infos at 0x7fd2e7fe46a8>
  File "log_example.py", line 22, in get_student_infos
    name, catgory, grade = log.split(' ')
    │     │        │       └ 'qianliu music'
    │     │        └ '90'
    │     └ 'chinese'
    └ 'wangwu'
ValueError: not enough values to unpack (expected 3, got 2)

django接入

思路和logging接入一样的. 例如有如下django项目:

☁  test_better_exceptions_django  tree
.
├── db.sqlite3
├── manage.py
└── test_better_exceptions_django
    ├── fm.py
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    ├── views.py
    └── wsgi.py

两处修改:

  • 增加一个fm.py文件:

    import logging
    from better_exceptions import format_exception
    class ExceptionFormatter(logging.Formatter):
        def formatException(self, ei):
            return format_exception(*ei)
    
  • 修改settings.py的LOGGING配置:

    LOGGING = {
        'version': 1,
        'disable_existing_loggers': True,
        'formatters': {
            'simple': {
                '()': 'test_better_exceptions_django.fm.ExceptionFormatter',
                'format': '%(levelname)s %(message)s'
            },
        },
        'handlers': {
            'console': {
                'level': 'INFO',
                'class': 'logging.StreamHandler',
                'formatter': 'simple'
            },
            'file': {
                'level': 'ERROR',
                'class': 'logging.FileHandler',
                'filename': os.path.join(BASE_DIR, "error.log"),
                'formatter': 'simple'
    
            }
        },
        'loggers': {
            'django': {
                'handlers': ['console', 'file'],
    
            }
        }
    }
    

    这里主要是自定义了一个formatters.

我是在请求里故意出发了一个异常,代码如下:

  • urls.py:

    from django.conf.urls import url
    from django.contrib import admin
    from . import views
    
    urlpatterns = [
        url(r'^$', views.index, name='index'),
    ]
    
    
  • views.py:

    from django.http import HttpResponse
    import logging
    logger = logging.getLogger('django')
    def index(request):
        a, b = 2, 0
        try:
            a / b
        except Exception as e:
            logger.exception(e)
        return HttpResponse("You have an excepion, see console and log")
    

接着打开浏览器,可以看到根目录下error.log文件内容:

☁  test_better_exceptions_django  cat error.log 
ERROR division by zero
Traceback (most recent call last):
  File "/vagrant_data/better_exceptions/test_better_exceptions_django/test_better_exceptions_django/views.py", line 12, in index
    a / b
    │   └ 0
    └ 2
ZeroDivisionError: division by zero

相关文章

  • python异常助手之better-exceptions

    简介 better-exceptions 可以在python异常发生时显示更多信息,帮助我们更好的发现问题. 介绍...

  • python better-exceptions工具

    安装方法 作用 使输出,更好看,出现错误能更直观的看出 变量名和变量值

  • V3.1.1 python异常与处理之怎么用

    一个编程的大白,我在学python的异常与处理。回顾前篇:V3.1 python异常与处理之异常基本语法) 现学习...

  • 2.1.3 Python面向对象之异常处理

    点击跳转笔记总目录 Python面向对象之异常处理 一、错误与异常 二、异常处理 三、什么时候用异常处理 一、错误...

  • 30.Python之异常处理

    Python之异常处理 什么时异常处理?异常就是程序运行时发生错误的信号(在程序出现错误时,则会产生一个异常,若程...

  • 24:python中的异常

    异常: 首先看看python的异常继承树 python的异常分为两种. 1、内建异常:就是python自己定义的异...

  • python之异常处理

    1.1 raise语句:引发异常 示例:raise Exception 1.2 内置的异常类 Except...

  • python 之 异常处理

    1.什么是异常(what) 异常:不正常的情况 不正常的情况,在程序中,会有两种体现: l自己造孽:写错代码了!错...

  • Python 之异常处理

    异常顾名思义就是不正常。在程序中,若程序出现错误导致程序中断,或者运行结果实现不了程序的功能。当程序在运行过程中,...

  • Python修炼之---异常

    1:概念:异常就是程序运行错误或则逻辑混乱 在python中,当python检测到一个错误时,解释器就无法正常运行...

网友评论

      本文标题:python异常助手之better-exceptions

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