过滤python日志记录模块以只记录异常的最后一行?

2wnc66cl  于 2023-02-11  发布在  Python
关注(0)|答案(1)|浏览(134)

我使用下面的代码来打印脚本中运行的python模块的异常:

except Exception as e:
          logging.info('yt-dlp initated a break', exc_info=True)

目前它输出的信息比我需要的多得多。
大致是这样的:

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/app/web_ripper.py", line 58, in subscriptions_loop
    ydl.download([url])
  File "/app/venv/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 3113, in download
    self.__download_wrapper(self.extract_info)(
  File "/app/venv/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 3086, in wrapper
    res = func(*args, **kwargs)
  File "/app/venv/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 1344, in extract_info
    return self.__extract_info(url, self.get_info_extractor(ie_key), download, extra_info, process)
  File "/app/venv/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 1371, in wrapper
    self.report_error(str(e), e.format_traceback())
  File "/app/venv/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 912, in report_error
    self.trouble(f'{self._format_err("ERROR:", self.Styles.ERROR)} {message}', *args, **kwargs)
  File "/app/venv/lib/python3.9/site-packages/yt_dlp/YoutubeDL.py", line 853, in trouble
    raise DownloadError(message, exc_info)
yt_dlp.utils.DownloadError: ERROR: [youtube:tab] Videogamedunkey: Unable to download API page: HTTP Error 404: Not Found

打印异常的最后一行的最有效方法是什么?

lx0bsm1f

lx0bsm1f1#

您可以使用自定义Formatter,它将处理您尝试记录的recordexc_text
下面的MyFormatter将检查记录是否有异常文本。如果没有,它将使用self.formatException创建它。然后,由于record.exc_text是一个字符串,将跟踪存储为文本,并使用\n作为行与行之间的分隔符,因此可以使用.split("\n")[-1]保留最后一行。

import logging

class MyFormatter(logging.Formatter):
    def format(self, record):
        # https://github.com/python/cpython/blob/main/Lib/logging/__init__.py#L711
        if not record.exc_text:
            record.exc_text = self.formatException(record.exc_info)
        record.exc_text = record.exc_text.split("\n")[-1]
        return super().format(record)

然后,添加以下代码以使用新的MyFormatter

def a(x):
    return b(x)

def b(x):
    return c(x)

def c(x):
    return d(x)

def d(x):
    return x / 0

logger = logging.getLogger("foobar")
logger.setLevel(logging.INFO)

stream_handler = logging.StreamHandler()
stream_handler.setFormatter(MyFormatter(fmt="%(name)s - %(levelname)s - %(message)s"))
logger.addHandler(stream_handler)

try:
    a(1)
except Exception as e:
    logger.info('yt-dlp initated a break', exc_info=True)

你会得到:

foobar - INFO - yt-dlp initated a break
ZeroDivisionError: division by zero

而不是以前的:

foobar - INFO - yt-dlp initated a break
Traceback (most recent call last):
  File "70704112.py", line 31, in <module>
    a(1)
  File "70704112.py", line 12, in a
    return b(x)
  File "70704112.py", line 15, in b
    return c(x)
  File "70704112.py", line 18, in c
    return d(x)
  File "70704112.py", line 21, in d
    return x / 0
ZeroDivisionError: division by zero

相关问题