mirror of
https://github.com/Textualize/rich.git
synced 2025-08-04 18:18:22 +00:00
handle exceptions with rich's logging handler
This commit is contained in:
parent
4e24f2ef1a
commit
0fac8d5eab
3 changed files with 95 additions and 11 deletions
|
@ -20,4 +20,17 @@ Rich logs won't render :ref:`console_markup` in logging by default as most libra
|
|||
|
||||
log.error("[bold red blink]Server is shutting down![/]", extra={"markup": True})
|
||||
|
||||
|
||||
Handle exceptions
|
||||
-------------------
|
||||
|
||||
Rich's :class:`~rich.logging.RichHandler` class can be configured to handle exceptions. Here's an example::
|
||||
|
||||
handler = RichHandler(handle_tracebacks=True)
|
||||
|
||||
try:
|
||||
1 / 0
|
||||
except ZeroDivisionError:
|
||||
log.exception("Exception message")
|
||||
|
||||
There are a number of options you can use to configure logging output, see the :class:`~rich.logging.RichHandler` reference for details.
|
||||
|
|
|
@ -29,6 +29,11 @@ class RichHandler(Handler):
|
|||
enable_link_path (bool, optional): Enable terminal link of path column to file. Defaults to True.
|
||||
highlighter (Highlighter, optional): Highlighter to style log messages, or None to use ReprHighlighter. Defaults to None.
|
||||
markup (bool, optional): Enable console markup in log messages. Defaults to False.
|
||||
handle_tracebacks (bool, optional): Enable rich tracebacks with syntax highlighting and formatting. Defaults to False.
|
||||
tracebacks_width (Optional[int], optional): Number of characters used to render tracebacks code. Defaults to 88.
|
||||
tracebacks_extra_lines (int, optional): Additional lines of code to render tracebacks. Defaults to 3.
|
||||
tracebacks_theme (str, optional): Override pygments theme used in traceback
|
||||
tracebacks_word_wrap (bool, optional): Enable word wrapping of long tracebacks lines. Defaults to False.
|
||||
|
||||
"""
|
||||
|
||||
|
@ -55,6 +60,11 @@ class RichHandler(Handler):
|
|||
enable_link_path: bool = True,
|
||||
highlighter: Highlighter = None,
|
||||
markup: bool = False,
|
||||
handle_tracebacks: bool = False,
|
||||
tracebacks_width: Optional[int] = 88,
|
||||
tracebacks_extra_lines: int = 3,
|
||||
tracebacks_theme: Optional[str] = None,
|
||||
tracebacks_word_wrap: bool = False,
|
||||
) -> None:
|
||||
super().__init__(level=level)
|
||||
self.console = console or get_console()
|
||||
|
@ -64,6 +74,11 @@ class RichHandler(Handler):
|
|||
)
|
||||
self.enable_link_path = enable_link_path
|
||||
self.markup = markup
|
||||
self.handle_tracebacks = handle_tracebacks
|
||||
self.tracebacks_width = tracebacks_width
|
||||
self.tracebacks_extra_lines = tracebacks_extra_lines
|
||||
self.tracebacks_theme = tracebacks_theme
|
||||
self.tracebacks_word_wrap = tracebacks_word_wrap
|
||||
|
||||
def emit(self, record: LogRecord) -> None:
|
||||
"""Invoked by logging."""
|
||||
|
@ -89,18 +104,26 @@ class RichHandler(Handler):
|
|||
if self.KEYWORDS:
|
||||
message_text.highlight_words(self.KEYWORDS, "logging.keyword")
|
||||
|
||||
self.console.print(
|
||||
self._log_render(
|
||||
self.console,
|
||||
[message_text],
|
||||
log_time=log_time,
|
||||
time_format=time_format,
|
||||
level=level,
|
||||
path=path,
|
||||
line_no=record.lineno,
|
||||
link_path=record.pathname if self.enable_link_path else None,
|
||||
if self.handle_tracebacks and record.exc_info:
|
||||
self.console.print_exception(
|
||||
width=self.tracebacks_width,
|
||||
extra_lines=self.tracebacks_extra_lines,
|
||||
theme=self.tracebacks_theme,
|
||||
word_wrap=self.tracebacks_word_wrap,
|
||||
)
|
||||
else:
|
||||
self.console.print(
|
||||
self._log_render(
|
||||
self.console,
|
||||
[message_text],
|
||||
log_time=log_time,
|
||||
time_format=time_format,
|
||||
level=level,
|
||||
path=path,
|
||||
line_no=record.lineno,
|
||||
link_path=record.pathname if self.enable_link_path else None,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
|
|
|
@ -29,6 +29,54 @@ def test_log():
|
|||
assert render == expected
|
||||
|
||||
|
||||
def test_exception():
|
||||
console = Console(
|
||||
file=io.StringIO(), force_terminal=True, width=80, color_system="truecolor"
|
||||
)
|
||||
handler_with_tracebacks = RichHandler(
|
||||
console=console, enable_link_path=False, handle_tracebacks=True
|
||||
)
|
||||
log.addHandler(handler_with_tracebacks)
|
||||
|
||||
try:
|
||||
1 / 0
|
||||
except ZeroDivisionError:
|
||||
log.exception("message")
|
||||
|
||||
render = handler_with_tracebacks.console.file.getvalue()
|
||||
print(render)
|
||||
|
||||
excpected = "ZeroDivisionError: \x1b[0mdivision by zero\n"
|
||||
assert excpected == render[-40:]
|
||||
assert render.count("\n") == 13
|
||||
|
||||
|
||||
def test_exception_with_extra_lines():
|
||||
console = Console(
|
||||
file=io.StringIO(), force_terminal=True, width=80, color_system="truecolor"
|
||||
)
|
||||
handler_extra_lines = RichHandler(
|
||||
console=console,
|
||||
enable_link_path=False,
|
||||
markup=True,
|
||||
handle_tracebacks=True,
|
||||
tracebacks_extra_lines=5,
|
||||
)
|
||||
log.addHandler(handler_extra_lines)
|
||||
|
||||
try:
|
||||
1 / 0
|
||||
except ZeroDivisionError:
|
||||
log.exception("message")
|
||||
|
||||
render = handler_extra_lines.console.file.getvalue()
|
||||
print(render)
|
||||
|
||||
excpected = "ZeroDivisionError: \x1b[0mdivision by zero\n"
|
||||
assert excpected == render[-40:]
|
||||
assert render.count("\n") == 17
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
render = make_log()
|
||||
print(render)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue