V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
Richard14
V2EX  ›  Python

Python 日志输出异常的正确姿势?

  •  1
     
  •   Richard14 · 53 天前 · 2900 次点击
    这是一个创建于 53 天前的主题,其中的信息可能已经有所发展或是发生改变。

    项目里为了程序在服务器上长期运行不会中断,在所有可能出异常的位置加了 try / except Exception as e ,但是有时候需要根据日志调试错误的时候,捕捉了 e 但是不太好在日志里查看,因为不能直接 raise ,这样的话程序就中断了,但是如果打印 e 的话又不包含整个错误的产生链,经常搞不清状况

    23 条回复    2022-06-25 14:04:40 +08:00
    Kinnice
        1
    Kinnice  
       53 天前
    简单做法: 把 e 的上下文中,你感觉需要分析的东西和 e 一块打出来
    StarainX
        2
    StarainX  
       53 天前
    logger.error(MSG, ext_info=1) 呢?
    banditt
        3
    banditt  
       53 天前
    traceback 这个库可以打印
    awanabe
        4
    awanabe  
       53 天前
    traceback.print_exc()
    把错误堆栈打出来
    SenLief
        5
    SenLief  
       53 天前
    loguru 也可以
    fkdtz
        6
    fkdtz  
       53 天前   ❤️ 1
    loguru 直接给你把调用栈写到日志里,还支持输出异常时的变量值便于排查问题,可以试试
    hsfzxjy
        7
    hsfzxjy  
       53 天前 via Android   ❤️ 2
    logger.exception()试试
    arischow
        8
    arischow  
       53 天前 via iPhone
    extra 这个 parameter 看看?
    Richard14
        9
    Richard14  
    OP
       53 天前
    @SenLief
    @fkdtz
    @hsfzxjy loguru 很好用,试了下 logger.exception 打印信息很全。一个问题是这个默认输出的是 error 级别的,有无方法调整成 warning 级别。有一些非关键错误想用 warning ,后面还会接一个日志分析,如果 error 就告警,warning 就忽略之类的。。。
    SenLief
        10
    SenLief  
       53 天前 via iPhone
    lucays
        11
    lucays  
       53 天前   ❤️ 1
    打印 e 的代码改成 logger.info(f'exception: {traceback.format_exc()}')就可以了
    当然如果可以,引入第三方库更好一些
    Morriaty
        12
    Morriaty  
       53 天前
    logging.error("message", exc_info=e) 就行了啊
    killva4624
        13
    killva4624  
       53 天前   ❤️ 1
    试试 sentry ?
    featureoverload
        14
    featureoverload  
       53 天前
    @Morriaty logger.error(msg, exc_info=True) / logging.error(msg, exc_info=True)
    ruanimal
        15
    ruanimal  
       53 天前
    “项目里为了程序在服务器上长期运行不会中断,在所有可能出异常的位置加了 try / except Exception as e”

    这个是祸乱之源, 只要最外层捕获错误即可。
    Morriaty
        16
    Morriaty  
       53 天前
    @featureoverload 应该传的就是 exc_info=e ,只不过 logging.__init__.py 里对其他传参做了兼容,源码是
    ```python
    if exc_info:
    if isinstance(exc_info, BaseException):
    exc_info = (type(exc_info), exc_info, exc_info.__traceback__)
    elif not isinstance(exc_info, tuple):
    exc_info = sys.exc_info()
    ```
    caqiko
        17
    caqiko  
       53 天前 via Android
    @ruanimal 我也是这样做的,内层只 raise ,然后在入口处捕获处理。不知道是不是最佳实践😅
    jaylengao
        18
    jaylengao  
       53 天前
    log.exception(e) 会打印完整错误堆栈
    ClericPy
        19
    ClericPy  
       52 天前
    想说的都被别人说完了... 主要也是 loguru 的那套

    不过之前公司打算上 ELK, 包装了一份 JSON log 感觉挺爽的, error 的 class + msg + traceback
    rationa1cuzz
        20
    rationa1cuzz  
       52 天前
    traceback 解君愁
    ruanimal
        21
    ruanimal  
       52 天前
    @caqiko

    一般情况如果内层只为打个日志然后无条件 raise 的话,其实根本就不应该捕获。
    内层应该只捕获当前函数可以处理的异常。
    louiswong2099
        22
    louiswong2099  
       52 天前
    sentry_sdk 这个也挺好用的,不知道适不适合你,可以捕获日志,还可以传到服务器慢慢看,分类都有,使用很简单:
    https://docs.sentry.io/platforms/python/usage/
    Macv1994
        23
    Macv1994  
       49 天前
    traceback 可以打印详细异常,写个异常捕捉的装饰器,要捕捉的地方加个装饰器就行了。
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2317 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 12:25 · PVG 20:25 · LAX 05:25 · JFK 08:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.