mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 11:18:54 -05:00
Various improvements in usage of Rich in Red (#4726)
* Use Rich's default console object instead of making one * Bump Rich to version 9.8.2 * Disable indent guides in tracebacks * Skip empty lines between stack levels in traceback rendering * Use full width of the terminal when printing tracebacks * Disabling syntax highlighting on the log messages * Make logger name bold * Make logger level bold * Make URLs in console bold * Change `bright_blue` and `blue` colors in syntax theme (NEEDS CHANGING) * Show only one line per stack level in tracebacks * Shuffle things in `redbot.logging` a bit * Change logging handler while redirecting stdout in Dev cog * Revert last two commits... This reverts commit cf563bd06a6ae398da12713ceef3db9cc903d902. This reverts commit 6dddf300726ddf89b8924441eed59b67b58faca0. * Change Rich console to always print to sys.stdout (therefore ignoring stdout redirects) * Pass cli_flags to init_logging() * Add a flag to set the amount of extra lines in rich tracebacks * First take on the syntax theme colors * Use the Windows trick * ARE YOU SERIOUS!? * Remove dead code * Use Monokai when Terminal application supports truecolor * Syntax theme update * Change logger name color * This is not needed * Adjust logging level colors * Add a flag for showing local variables in Rich tracebacks * change imports a bit * Remove usage of blue color fully * Stop highlighting in Red-DiscordBot splash * Fix unreadable paths in tracebacks * Make CRITICAL logging level more readable * Make time in logs more readable * Fix the first row being bolded in tables * Update rich to 9.9.0
This commit is contained in:
parent
663876fba3
commit
7df1570d51
@ -337,7 +337,7 @@ async def run_bot(red: Red, cli_flags: Namespace) -> None:
|
|||||||
redbot.logging.init_logging(
|
redbot.logging.init_logging(
|
||||||
level=cli_flags.logging_level,
|
level=cli_flags.logging_level,
|
||||||
location=data_manager.core_data_path() / "logs",
|
location=data_manager.core_data_path() / "logs",
|
||||||
force_rich_logging=cli_flags.rich_logging,
|
cli_flags=cli_flags,
|
||||||
)
|
)
|
||||||
|
|
||||||
log.debug("====Basic Config====")
|
log.debug("====Basic Config====")
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import colorama as _colorama
|
|
||||||
import discord as _discord
|
import discord as _discord
|
||||||
|
|
||||||
from .. import __version__, version_info, VersionInfo
|
from .. import __version__, version_info, VersionInfo
|
||||||
@ -7,7 +6,5 @@ from .utils.safety import warn_unsafe as _warn_unsafe
|
|||||||
|
|
||||||
__all__ = ["Config", "__version__", "version_info", "VersionInfo"]
|
__all__ = ["Config", "__version__", "version_info", "VersionInfo"]
|
||||||
|
|
||||||
_colorama.init()
|
|
||||||
|
|
||||||
# Prevent discord PyNaCl missing warning
|
# Prevent discord PyNaCl missing warning
|
||||||
_discord.voice_client.VoiceClient.warn_nacl = False
|
_discord.voice_client.VoiceClient.warn_nacl = False
|
||||||
|
|||||||
@ -29,7 +29,6 @@ from typing import (
|
|||||||
overload,
|
overload,
|
||||||
)
|
)
|
||||||
from types import MappingProxyType
|
from types import MappingProxyType
|
||||||
from rich.console import Console
|
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands as dpy_commands
|
from discord.ext import commands as dpy_commands
|
||||||
@ -224,9 +223,6 @@ class RedBase(
|
|||||||
|
|
||||||
self._deletion_requests: MutableMapping[int, asyncio.Lock] = weakref.WeakValueDictionary()
|
self._deletion_requests: MutableMapping[int, asyncio.Lock] = weakref.WeakValueDictionary()
|
||||||
|
|
||||||
# Although I see the use of keeping this public, lets rather make it private.
|
|
||||||
self._rich_console = Console()
|
|
||||||
|
|
||||||
def set_help_formatter(self, formatter: commands.help.HelpFormatterABC):
|
def set_help_formatter(self, formatter: commands.help.HelpFormatterABC):
|
||||||
"""
|
"""
|
||||||
Set's Red's help formatter.
|
Set's Red's help formatter.
|
||||||
|
|||||||
@ -263,6 +263,20 @@ def parse_cli_flags(args):
|
|||||||
default=None,
|
default=None,
|
||||||
help="Forcefully disables the Rich logging handlers.",
|
help="Forcefully disables the Rich logging handlers.",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--rich-traceback-extra-lines",
|
||||||
|
type=positive_int,
|
||||||
|
default=0,
|
||||||
|
help="Set the number of additional lines of code before and after the executed line"
|
||||||
|
" that should be shown in tracebacks generated by Rich.\n"
|
||||||
|
"Useful for development.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--rich-traceback-show-locals",
|
||||||
|
action="store_true",
|
||||||
|
help="Enable showing local variables in tracebacks generated by Rich.\n"
|
||||||
|
"Useful for development.",
|
||||||
|
)
|
||||||
|
|
||||||
args = parser.parse_args(args)
|
args = parser.parse_args(args)
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,6 @@ from datetime import datetime, timedelta
|
|||||||
import aiohttp
|
import aiohttp
|
||||||
import discord
|
import discord
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
from colorama import Fore, Style, init
|
|
||||||
from pkg_resources import DistributionNotFound
|
from pkg_resources import DistributionNotFound
|
||||||
from redbot.core import data_manager
|
from redbot.core import data_manager
|
||||||
|
|
||||||
@ -33,15 +32,16 @@ from .utils._internal_utils import (
|
|||||||
)
|
)
|
||||||
from .utils.chat_formatting import inline, bordered, format_perms_list, humanize_timedelta
|
from .utils.chat_formatting import inline, bordered, format_perms_list, humanize_timedelta
|
||||||
|
|
||||||
|
import rich
|
||||||
|
from rich import box
|
||||||
from rich.table import Table
|
from rich.table import Table
|
||||||
from rich.columns import Columns
|
from rich.columns import Columns
|
||||||
from rich.panel import Panel
|
from rich.panel import Panel
|
||||||
from rich.text import Text
|
from rich.text import Text
|
||||||
|
|
||||||
log = logging.getLogger("red")
|
log = logging.getLogger("red")
|
||||||
init()
|
|
||||||
|
|
||||||
INTRO = r"""[red]
|
INTRO = r"""
|
||||||
______ _ ______ _ _ ______ _
|
______ _ ______ _ _ ______ _
|
||||||
| ___ \ | | | _ (_) | | | ___ \ | |
|
| ___ \ | | | _ (_) | | | ___ \ | |
|
||||||
| |_/ /___ __| | ______ | | | |_ ___ ___ ___ _ __ __| | | |_/ / ___ | |_
|
| |_/ /___ __| | ______ | | | |_ ___ ___ ___ _ __ __| | | |_/ / ___ | |_
|
||||||
@ -88,14 +88,14 @@ def init_events(bot, cli_flags):
|
|||||||
red_pkg = pkg_resources.get_distribution("Red-DiscordBot")
|
red_pkg = pkg_resources.get_distribution("Red-DiscordBot")
|
||||||
dpy_version = discord.__version__
|
dpy_version = discord.__version__
|
||||||
|
|
||||||
table_general_info = Table(show_edge=False, show_header=False)
|
table_general_info = Table(show_edge=False, show_header=False, box=box.MINIMAL)
|
||||||
table_general_info.add_row("Prefixes", ", ".join(prefixes))
|
table_general_info.add_row("Prefixes", ", ".join(prefixes))
|
||||||
table_general_info.add_row("Language", lang)
|
table_general_info.add_row("Language", lang)
|
||||||
table_general_info.add_row("Red version", red_version)
|
table_general_info.add_row("Red version", red_version)
|
||||||
table_general_info.add_row("Discord.py version", dpy_version)
|
table_general_info.add_row("Discord.py version", dpy_version)
|
||||||
table_general_info.add_row("Storage type", data_manager.storage_type())
|
table_general_info.add_row("Storage type", data_manager.storage_type())
|
||||||
|
|
||||||
table_counts = Table(show_edge=False, show_header=False)
|
table_counts = Table(show_edge=False, show_header=False, box=box.MINIMAL)
|
||||||
# String conversion is needed as Rich doesn't deal with ints
|
# String conversion is needed as Rich doesn't deal with ints
|
||||||
table_counts.add_row("Shards", str(bot.shard_count))
|
table_counts.add_row("Shards", str(bot.shard_count))
|
||||||
table_counts.add_row("Servers", str(guilds))
|
table_counts.add_row("Servers", str(guilds))
|
||||||
@ -114,8 +114,8 @@ def init_events(bot, cli_flags):
|
|||||||
).format(pypi_version, red_version)
|
).format(pypi_version, red_version)
|
||||||
rich_outdated_message = (
|
rich_outdated_message = (
|
||||||
f"[red]Outdated version![/red]\n"
|
f"[red]Outdated version![/red]\n"
|
||||||
f"[red]!!![/red]Version {pypi_version} is available, "
|
f"[red]!!![/red]Version [cyan]{pypi_version}[/] is available, "
|
||||||
f"but you're using {red_version}[red]!!![/red]"
|
f"but you're using [cyan]{red_version}[/][red]!!![/red]"
|
||||||
)
|
)
|
||||||
current_python = platform.python_version()
|
current_python = platform.python_version()
|
||||||
extra_update = _(
|
extra_update = _(
|
||||||
@ -167,9 +167,10 @@ def init_events(bot, cli_flags):
|
|||||||
).format(py_version=current_python, req_py=py_version_req)
|
).format(py_version=current_python, req_py=py_version_req)
|
||||||
outdated_red_message += extra_update
|
outdated_red_message += extra_update
|
||||||
|
|
||||||
bot._rich_console.print(INTRO)
|
rich_console = rich.get_console()
|
||||||
|
rich_console.print(INTRO, style="red", markup=False, highlight=False)
|
||||||
if guilds:
|
if guilds:
|
||||||
bot._rich_console.print(
|
rich_console.print(
|
||||||
Columns(
|
Columns(
|
||||||
[Panel(table_general_info, title=str(bot.user.name)), Panel(table_counts)],
|
[Panel(table_general_info, title=str(bot.user.name)), Panel(table_counts)],
|
||||||
equal=True,
|
equal=True,
|
||||||
@ -177,23 +178,21 @@ def init_events(bot, cli_flags):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
bot._rich_console.print(Columns([Panel(table_general_info, title=str(bot.user.name))]))
|
rich_console.print(Columns([Panel(table_general_info, title=str(bot.user.name))]))
|
||||||
|
|
||||||
bot._rich_console.print(
|
rich_console.print(
|
||||||
"Loaded {} cogs with {} commands".format(len(bot.cogs), len(bot.commands))
|
"Loaded {} cogs with {} commands".format(len(bot.cogs), len(bot.commands))
|
||||||
)
|
)
|
||||||
|
|
||||||
if invite_url:
|
if invite_url:
|
||||||
bot._rich_console.print(
|
rich_console.print(f"\nInvite URL: {Text(invite_url, style=f'link {invite_url}')}")
|
||||||
f"\nInvite URL: {Text(invite_url, style=f'link {invite_url}')}"
|
|
||||||
)
|
|
||||||
# We generally shouldn't care if the client supports it or not as Rich deals with it.
|
# We generally shouldn't care if the client supports it or not as Rich deals with it.
|
||||||
if not guilds:
|
if not guilds:
|
||||||
bot._rich_console.print(
|
rich_console.print(
|
||||||
f"Looking for a quick guide on setting up Red? Checkout {Text('https://start.discord.red', style='link https://start.discord.red}')}"
|
f"Looking for a quick guide on setting up Red? Checkout {Text('https://start.discord.red', style='link https://start.discord.red}')}"
|
||||||
)
|
)
|
||||||
if rich_outdated_message:
|
if rich_outdated_message:
|
||||||
bot._rich_console.print(rich_outdated_message)
|
rich_console.print(rich_outdated_message)
|
||||||
|
|
||||||
if not bot.owner_ids:
|
if not bot.owner_ids:
|
||||||
# we could possibly exit here in future
|
# we could possibly exit here in future
|
||||||
@ -404,37 +403,3 @@ def init_events(bot, cli_flags):
|
|||||||
uuid = c.unique_identifier
|
uuid = c.unique_identifier
|
||||||
group_data = c.custom_groups
|
group_data = c.custom_groups
|
||||||
await bot._config.custom("CUSTOM_GROUPS", c.cog_name, uuid).set(group_data)
|
await bot._config.custom("CUSTOM_GROUPS", c.cog_name, uuid).set(group_data)
|
||||||
|
|
||||||
|
|
||||||
def _get_startup_screen_specs():
|
|
||||||
"""Get specs for displaying the startup screen on stdout.
|
|
||||||
|
|
||||||
This is so we don't get encoding errors when trying to print unicode
|
|
||||||
emojis to stdout (particularly with Windows Command Prompt).
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
`tuple`
|
|
||||||
Tuple in the form (`str`, `str`, `bool`) containing (in order) the
|
|
||||||
on symbol, off symbol and whether or not the border should be pure ascii.
|
|
||||||
|
|
||||||
"""
|
|
||||||
encoder = codecs.getencoder(sys.stdout.encoding)
|
|
||||||
check_mark = "\N{SQUARE ROOT}"
|
|
||||||
try:
|
|
||||||
encoder(check_mark)
|
|
||||||
except UnicodeEncodeError:
|
|
||||||
on_symbol = "[X]"
|
|
||||||
off_symbol = "[ ]"
|
|
||||||
else:
|
|
||||||
on_symbol = check_mark
|
|
||||||
off_symbol = "X"
|
|
||||||
|
|
||||||
try:
|
|
||||||
encoder("┌┐└┘─│") # border symbols
|
|
||||||
except UnicodeEncodeError:
|
|
||||||
ascii_border = True
|
|
||||||
else:
|
|
||||||
ascii_border = False
|
|
||||||
|
|
||||||
return on_symbol, off_symbol, ascii_border
|
|
||||||
|
|||||||
@ -1,19 +1,37 @@
|
|||||||
|
import argparse
|
||||||
import logging.handlers
|
import logging.handlers
|
||||||
import pathlib
|
import pathlib
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from typing import List, Tuple, Optional, Union
|
from typing import List, Tuple, Optional
|
||||||
from logging import LogRecord
|
from logging import LogRecord
|
||||||
from datetime import datetime # This clearly never leads to confusion...
|
from datetime import datetime # This clearly never leads to confusion...
|
||||||
from os import isatty
|
from os import isatty
|
||||||
|
|
||||||
from rich._log_render import LogRender
|
import rich
|
||||||
|
from pygments.styles.monokai import MonokaiStyle
|
||||||
|
from pygments.token import (
|
||||||
|
Comment,
|
||||||
|
Error,
|
||||||
|
Keyword,
|
||||||
|
Name,
|
||||||
|
Number,
|
||||||
|
Operator,
|
||||||
|
String,
|
||||||
|
Token,
|
||||||
|
)
|
||||||
|
from rich._log_render import LogRender # DEP-WARN
|
||||||
|
from rich.console import render_group
|
||||||
from rich.containers import Renderables
|
from rich.containers import Renderables
|
||||||
|
from rich.highlighter import NullHighlighter
|
||||||
from rich.logging import RichHandler
|
from rich.logging import RichHandler
|
||||||
|
from rich.style import Style
|
||||||
|
from rich.syntax import ANSISyntaxTheme, PygmentsSyntaxTheme
|
||||||
from rich.table import Table
|
from rich.table import Table
|
||||||
from rich.text import Text
|
from rich.text import Text
|
||||||
from rich.traceback import Traceback
|
from rich.theme import Theme
|
||||||
|
from rich.traceback import PathHighlighter, Traceback
|
||||||
|
|
||||||
|
|
||||||
MAX_OLD_LOGS = 8
|
MAX_OLD_LOGS = 8
|
||||||
@ -109,6 +127,37 @@ class RotatingFileHandler(logging.handlers.RotatingFileHandler):
|
|||||||
self.stream = self._open()
|
self.stream = self._open()
|
||||||
|
|
||||||
|
|
||||||
|
SYNTAX_THEME = {
|
||||||
|
Token: Style(),
|
||||||
|
Comment: Style(color="bright_black"),
|
||||||
|
Keyword: Style(color="cyan", bold=True),
|
||||||
|
Keyword.Constant: Style(color="bright_magenta"),
|
||||||
|
Keyword.Namespace: Style(color="bright_red"),
|
||||||
|
Operator: Style(bold=True),
|
||||||
|
Operator.Word: Style(color="cyan", bold=True),
|
||||||
|
Name.Builtin: Style(bold=True),
|
||||||
|
Name.Builtin.Pseudo: Style(color="bright_red"),
|
||||||
|
Name.Exception: Style(bold=True),
|
||||||
|
Name.Class: Style(color="bright_green"),
|
||||||
|
Name.Function: Style(color="bright_green"),
|
||||||
|
String: Style(color="yellow"),
|
||||||
|
Number: Style(color="cyan"),
|
||||||
|
Error: Style(bgcolor="red"),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class FixedMonokaiStyle(MonokaiStyle):
|
||||||
|
styles = {**MonokaiStyle.styles, Token: "#f8f8f2"}
|
||||||
|
|
||||||
|
|
||||||
|
class RedTraceback(Traceback):
|
||||||
|
@render_group()
|
||||||
|
def _render_stack(self, stack):
|
||||||
|
for obj in super()._render_stack.__wrapped__(self, stack):
|
||||||
|
if obj != "":
|
||||||
|
yield obj
|
||||||
|
|
||||||
|
|
||||||
class RedLogRender(LogRender):
|
class RedLogRender(LogRender):
|
||||||
def __call__(
|
def __call__(
|
||||||
self,
|
self,
|
||||||
@ -155,7 +204,7 @@ class RedLogRender(LogRender):
|
|||||||
|
|
||||||
if logger_name:
|
if logger_name:
|
||||||
logger_name_text = Text()
|
logger_name_text = Text()
|
||||||
logger_name_text.append(f"[{logger_name}]")
|
logger_name_text.append(f"[{logger_name}]", style="bright_black")
|
||||||
row.append(logger_name_text)
|
row.append(logger_name_text)
|
||||||
|
|
||||||
output.add_row(*row)
|
output.add_row(*row)
|
||||||
@ -174,6 +223,19 @@ class RedRichHandler(RichHandler):
|
|||||||
level_width=self._log_render.level_width,
|
level_width=self._log_render.level_width,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_level_text(self, record: LogRecord) -> Text:
|
||||||
|
"""Get the level name from the record.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
record (LogRecord): LogRecord instance.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Text: A tuple of the style and level name.
|
||||||
|
"""
|
||||||
|
level_text = super().get_level_text(record)
|
||||||
|
level_text.stylize("bold")
|
||||||
|
return level_text
|
||||||
|
|
||||||
def emit(self, record: LogRecord) -> None:
|
def emit(self, record: LogRecord) -> None:
|
||||||
"""Invoked by logging."""
|
"""Invoked by logging."""
|
||||||
path = pathlib.Path(record.pathname).name
|
path = pathlib.Path(record.pathname).name
|
||||||
@ -187,7 +249,7 @@ class RedRichHandler(RichHandler):
|
|||||||
exc_type, exc_value, exc_traceback = record.exc_info
|
exc_type, exc_value, exc_traceback = record.exc_info
|
||||||
assert exc_type is not None
|
assert exc_type is not None
|
||||||
assert exc_value is not None
|
assert exc_value is not None
|
||||||
traceback = Traceback.from_exception(
|
traceback = RedTraceback.from_exception(
|
||||||
exc_type,
|
exc_type,
|
||||||
exc_value,
|
exc_value,
|
||||||
exc_traceback,
|
exc_traceback,
|
||||||
@ -198,6 +260,7 @@ class RedRichHandler(RichHandler):
|
|||||||
show_locals=self.tracebacks_show_locals,
|
show_locals=self.tracebacks_show_locals,
|
||||||
locals_max_length=self.locals_max_length,
|
locals_max_length=self.locals_max_length,
|
||||||
locals_max_string=self.locals_max_string,
|
locals_max_string=self.locals_max_string,
|
||||||
|
indent_guides=False,
|
||||||
)
|
)
|
||||||
message = record.getMessage()
|
message = record.getMessage()
|
||||||
|
|
||||||
@ -215,7 +278,7 @@ class RedRichHandler(RichHandler):
|
|||||||
self.console.print(
|
self.console.print(
|
||||||
self._log_render(
|
self._log_render(
|
||||||
self.console,
|
self.console,
|
||||||
[message_text] if not traceback else [message_text, traceback],
|
[message_text],
|
||||||
log_time=log_time,
|
log_time=log_time,
|
||||||
time_format=time_format,
|
time_format=time_format,
|
||||||
level=level,
|
level=level,
|
||||||
@ -225,11 +288,11 @@ class RedRichHandler(RichHandler):
|
|||||||
logger_name=record.name,
|
logger_name=record.name,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
if traceback:
|
||||||
|
self.console.print(traceback)
|
||||||
|
|
||||||
|
|
||||||
def init_logging(
|
def init_logging(level: int, location: pathlib.Path, cli_flags: argparse.Namespace) -> None:
|
||||||
level: int, location: pathlib.Path, force_rich_logging: Union[bool, None]
|
|
||||||
) -> None:
|
|
||||||
root_logger = logging.getLogger()
|
root_logger = logging.getLogger()
|
||||||
|
|
||||||
base_logger = logging.getLogger("red")
|
base_logger = logging.getLogger("red")
|
||||||
@ -239,12 +302,31 @@ def init_logging(
|
|||||||
warnings_logger = logging.getLogger("py.warnings")
|
warnings_logger = logging.getLogger("py.warnings")
|
||||||
warnings_logger.setLevel(logging.WARNING)
|
warnings_logger.setLevel(logging.WARNING)
|
||||||
|
|
||||||
|
rich_console = rich.get_console()
|
||||||
|
rich.reconfigure(tab_size=4)
|
||||||
|
rich_console.push_theme(
|
||||||
|
Theme(
|
||||||
|
{
|
||||||
|
"log.time": Style(dim=True),
|
||||||
|
"logging.level.warning": Style(color="yellow"),
|
||||||
|
"logging.level.critical": Style(color="white", bgcolor="red"),
|
||||||
|
"repr.number": Style(color="cyan"),
|
||||||
|
"repr.url": Style(underline=True, italic=True, bold=False, color="cyan"),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
rich_console.file = sys.stdout
|
||||||
|
# This is terrible solution, but it's the best we can do if we want the paths in tracebacks
|
||||||
|
# to be visible. Rich uses `pygments.string` style which is fine, but it also uses
|
||||||
|
# this highlighter which dims most of the path and therefore makes it unreadable on Mac.
|
||||||
|
PathHighlighter.highlights = []
|
||||||
|
|
||||||
enable_rich_logging = False
|
enable_rich_logging = False
|
||||||
|
|
||||||
if isatty(0) and force_rich_logging is None:
|
if isatty(0) and cli_flags.rich_logging is None:
|
||||||
# Check if the bot thinks it has a active terminal.
|
# Check if the bot thinks it has a active terminal.
|
||||||
enable_rich_logging = True
|
enable_rich_logging = True
|
||||||
elif force_rich_logging is True:
|
elif cli_flags.rich_logging is True:
|
||||||
enable_rich_logging = True
|
enable_rich_logging = True
|
||||||
|
|
||||||
file_formatter = logging.Formatter(
|
file_formatter = logging.Formatter(
|
||||||
@ -253,7 +335,18 @@ def init_logging(
|
|||||||
if enable_rich_logging is True:
|
if enable_rich_logging is True:
|
||||||
rich_formatter = logging.Formatter("{message}", datefmt="[%X]", style="{")
|
rich_formatter = logging.Formatter("{message}", datefmt="[%X]", style="{")
|
||||||
|
|
||||||
stdout_handler = RedRichHandler(rich_tracebacks=True, show_path=False)
|
stdout_handler = RedRichHandler(
|
||||||
|
rich_tracebacks=True,
|
||||||
|
show_path=False,
|
||||||
|
highlighter=NullHighlighter(),
|
||||||
|
tracebacks_extra_lines=cli_flags.rich_traceback_extra_lines,
|
||||||
|
tracebacks_show_locals=cli_flags.rich_traceback_show_locals,
|
||||||
|
tracebacks_theme=(
|
||||||
|
PygmentsSyntaxTheme(FixedMonokaiStyle)
|
||||||
|
if rich_console.color_system == "truecolor"
|
||||||
|
else ANSISyntaxTheme(SYNTAX_THEME)
|
||||||
|
),
|
||||||
|
)
|
||||||
stdout_handler.setFormatter(rich_formatter)
|
stdout_handler.setFormatter(rich_formatter)
|
||||||
else:
|
else:
|
||||||
stdout_handler = logging.StreamHandler(sys.stdout)
|
stdout_handler = logging.StreamHandler(sys.stdout)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user