【问题标题】:Store unhandled exceptions in log file在日志文件中存储未处理的异常
【发布时间】:2021-04-29 12:34:09
【问题描述】:

我正在尝试为我的 python 脚本构建一个记录器logger_script.py

  • 输出具有可自定义日志级别的日志文件。
  • 输出带有可自定义日志级别的控制台输出(不一定等于日志文件的级别)
  • 将未处理的异常记录到日志文件和控制台中

我通过遵循“https://stackoverflow.com/questions/29087297/is-there-a-way-to-change-the-filemode-for-a-logger-object”的答案实现了前两点- 那是未配置/29087645”。我根据自己的需要对其进行了调整,现在看起来像:

import sys
import logging

def create_logger(log_filename, logfile_level, console_level):

    # create logger and file handler
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.DEBUG)

    fh = logging.FileHandler(log_filename, mode='w')
    fh.setLevel(logfile_level)

    # create console handler with independent log level
    ch = logging.StreamHandler(stream=sys.stdout)
    ch.setLevel(console_level)

    formatter = logging.Formatter('[%(asctime)s] %(levelname)8s: %(message)s' +
                                  ' (%(filename)s:%(lineno)s)',
                                  datefmt='%m-%d, %H:%M:%S')
    fh.setFormatter(formatter)
    ch.setFormatter(formatter)

    if (logger.hasHandlers()): #clear pre-existing logs (?)
        logger.handlers.clear() 
        
    logger.addHandler(ch)
    logger.addHandler(fh)
    
    return logger

#create the logger: file log + console output
logger = create_logger("LogFile.log", logging.INFO, logging.WARNING)

#####  piece of code with handled exceptions:  #####
beta = 3

while beta > -3:
    try:
        2/beta
        logger.info("division successful".rjust(20))
    except ZeroDivisionError:
        logger.exception("ZeroDivisionError".rjust(20))    
    beta -= 1

##### piece of code with unhandled exception  ##### 
gamma = 1/0
    

但是,当运行带有未处理异常的代码时(请参阅最后一行),这些异常不会传递到日志文件,只会传递到控制台。

我听从Logging uncaught exceptions in Python 的建议并添加了以下sn-p;

def handle_exception(exc_type, exc_value, exc_traceback):
    if issubclass(exc_type, KeyboardInterrupt):
        sys.__excepthook__(exc_type, exc_value, exc_traceback)
        return

    logger.error("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback))

sys.excepthook = handle_exception

在记录器创建行之前或之后,但在我的情况下不起作用。

如何让未处理的异常连同它们的回溯消息一起出现?

我想避免将整个代码封装到try: except 语句中。

【问题讨论】:

  • “未处理的异常”需要处理才能被记录 - except 它,记录它,但之后只是重新引发

标签: python logging


【解决方案1】:

我想避免将整个代码封装到 try: except 语句中。

我建议在 def main() 中编写整个代码 - 如果您决定重用部分代码以便在导入文件时不会执行任何代码,这将非常有用。 :)

然后你就可以在if __name__== "__main__":做一个包罗万象的事情了:

if __name__ == "__main__":
    try:
        main()
    except Exception as e: 
        logger.exception("Program stopped because of a critical error.")
        raise

[这就是我在自己的代码中的做法。它不需要任何技巧,我确实添加了它以防发生意外异常,以便我以后可以调试。]

raise 重新引发了被捕获的相同错误 - 所以它不会被外界捕获。 .exception.error 做同样的事情,但它自己包含异常信息。

【讨论】:

    猜你喜欢
    • 2012-10-06
    • 1970-01-01
    • 2011-08-08
    • 2018-09-05
    • 1970-01-01
    • 2018-10-14
    • 1970-01-01
    • 2013-11-22
    • 1970-01-01
    相关资源
    最近更新 更多