自定义异常默认日志

时间:2018-03-07 11:10:50

标签: python exception logging

我构建了自定义异常,接受参数并从常量格式化自己的消息。他们还打印到标准输出,以便用户理解这个问题。

例如:

document.getElementById('latitude').value = position.coords.latitude;
document.getElementById('longitude').value = position.coords.longitude;

我还想记录抛出的异常,最简单的方法是:

defs.py:
PATH_NOT_FOUND_ERROR = 'Cannot find path "{}"'

exceptions.py:
class PathNotFound(BaseCustomException):
    """Specified path was not found."""

    def __init__(self, path):
        msg = PATH_NOT_FOUND_ERROR.format(path)
        print(msg)
        super(PathNotFound, self).__init__(msg)

some_module.py
raise PathNotFound(some_invalid_path)

但是在整个代码中执行此操作似乎是多余的,特别是它使常量毫无意义,因为如果我决定更改我需要更改记录器措辞的措辞。

我尝试做一些事情,比如将记录器移动到异常类,但却让我失去了相关的logger.debug('path {} not found'.format(some_invalid_path) raise PathNotFound(some_invalid_path) 属性,例如LogRecordnamemodule,{ {1}}等。这种方法也失去了filename

有没有办法记录异常并保留元数据而不进行记录,然后每次都提高?

1 个答案:

答案 0 :(得分:2)

如果有人有兴趣,这是一个有效的解决方案

想法是找到提升者的框架并从那里提取相关信息。 还必须覆盖logging.makeRecord以允许我覆盖内部LogRecord属性

设置记录

class MyLogger(logging.Logger):
    """Custom Logger."""

    def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None):
        """Override default logger to allow overridding internal attributes."""
        if six.PY2:
            rv = logging.LogRecord(name, level, fn, lno, msg, args, exc_info, func)
        else:
            rv = logging.LogRecord(name, level, fn, lno, msg, args, exc_info, func, sinfo)

        if extra is not None:
            for key in extra:
                # if (key in ["message", "asctime"]) or (key in rv.__dict__):
                #     raise KeyError("Attempt to overwrite %r in LogRecord" % key)
                rv.__dict__[key] = extra[key]
        return rv



logging.setLoggerClass(MyLogger)
logger = logging.getLogger(__name__)

自定义异常处理程序

class BaseCustomException(Exception):
    """Specified path was not found."""

    def __init__(self, path):
    """Override message with defined const."""
    try:
        raise ZeroDivisionError
    except ZeroDivisionError:
        # Find the traceback frame that raised this exception
        exception_frame = sys.exc_info()[2].tb_frame.f_back.f_back

    exception_stack = traceback.extract_stack(exception_frame, limit=1)[0]
    filename, lineno, funcName, tb_msg = exception_stack

    extra = {'filename': os.path.basename(filename), 'lineno': lineno, 'funcName': funcName}
    logger.debug(msg, extra=extra)
    traceback.print_stack(exception_frame)
    super(BaseCustomException, self).__init__(msg)