Initial commit
This commit is contained in:
99
BetterADBSync/SAOLogging.py
Executable file
99
BetterADBSync/SAOLogging.py
Executable file
@@ -0,0 +1,99 @@
|
||||
"""Nice logging, with colors on Linux."""
|
||||
|
||||
from typing import Any, Union
|
||||
import logging
|
||||
import sys
|
||||
|
||||
class ColoredFormatter(logging.Formatter):
|
||||
"""Logging Formatter to add colors"""
|
||||
|
||||
fg_bright_blue = "\x1b[94m"
|
||||
fg_yellow = "\x1b[33m"
|
||||
fg_red = "\x1b[31m"
|
||||
fg_bright_red_bold = "\x1b[91;1m"
|
||||
reset = "\x1b[0m"
|
||||
|
||||
def __init__(self, fmt, datefmt):
|
||||
super().__init__()
|
||||
self.messagefmt = fmt
|
||||
self.datefmt = datefmt
|
||||
|
||||
self.formats = {
|
||||
logging.DEBUG: "{}{}{}".format(self.fg_bright_blue, self.messagefmt, self.reset),
|
||||
logging.INFO: "{}".format(self.messagefmt),
|
||||
logging.WARNING: "{}{}{}".format(self.fg_yellow, self.messagefmt, self.reset),
|
||||
logging.ERROR: "{}{}{}".format(self.fg_red, self.messagefmt, self.reset),
|
||||
logging.CRITICAL: "{}{}{}".format(self.fg_bright_red_bold, self.messagefmt, self.reset)
|
||||
}
|
||||
|
||||
self.formatters = {
|
||||
logging.DEBUG: logging.Formatter(self.formats[logging.DEBUG], datefmt = self.datefmt),
|
||||
logging.INFO: logging.Formatter(self.formats[logging.INFO], datefmt = self.datefmt),
|
||||
logging.WARNING: logging.Formatter(self.formats[logging.WARNING], datefmt = self.datefmt),
|
||||
logging.ERROR: logging.Formatter(self.formats[logging.ERROR], datefmt = self.datefmt),
|
||||
logging.CRITICAL: logging.Formatter(self.formats[logging.CRITICAL], datefmt = self.datefmt)
|
||||
}
|
||||
|
||||
def format(self, record):
|
||||
formatter = self.formatters[record.levelno]
|
||||
return formatter.format(record)
|
||||
|
||||
def setup_root_logger(
|
||||
no_color: bool = False,
|
||||
verbosity_level: int = 0,
|
||||
quietness_level: int = 0,
|
||||
messagefmt: str = "[%(asctime)s][%(levelname)s] %(message)s (%(filename)s:%(lineno)d)",
|
||||
messagefmt_verbose: str = "[%(asctime)s][%(levelname)s] %(message)s (%(filename)s:%(lineno)d)",
|
||||
datefmt: str = "%Y-%m-%d %H:%M:%S"
|
||||
):
|
||||
messagefmt_to_use = messagefmt_verbose if verbosity_level else messagefmt
|
||||
logging_level = 10 * (2 + quietness_level - verbosity_level)
|
||||
if not no_color and sys.platform == "linux":
|
||||
formatter_class = ColoredFormatter
|
||||
else:
|
||||
formatter_class = logging.Formatter
|
||||
|
||||
root_logger = logging.getLogger()
|
||||
root_logger.setLevel(logging_level)
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setFormatter(formatter_class(fmt = messagefmt_to_use, datefmt = datefmt))
|
||||
root_logger.addHandler(console_handler)
|
||||
|
||||
def logging_fatal(message, log_stack_info: bool = True, exit_code: int = 1):
|
||||
logging.critical(message)
|
||||
logging.debug("Stack Trace", stack_info = log_stack_info)
|
||||
logging.critical("Exiting")
|
||||
raise SystemExit(exit_code)
|
||||
|
||||
def log_tree(title, tree, finals = None, log_leaves_types = True, logging_level = logging.INFO):
|
||||
"""Log tree nicely if it is a dictionary.
|
||||
log_leaves_types can be False to log no leaves, True to log all leaves, or a tuple of types for which to log."""
|
||||
if finals is None:
|
||||
finals = []
|
||||
if not isinstance(tree, dict):
|
||||
logging.log(msg = "{}{}{}".format(
|
||||
"".join([" " if final else "│" for final in finals[:-1]] + ["└" if final else "├" for final in finals[-1:]]),
|
||||
title,
|
||||
": {}".format(tree) if log_leaves_types is not False and (log_leaves_types is True or isinstance(tree, log_leaves_types)) else ""
|
||||
), level = logging_level)
|
||||
else:
|
||||
logging.log(msg = "{}{}".format(
|
||||
"".join([" " if final else "│" for final in finals[:-1]] + ["└" if final else "├" for final in finals[-1:]]),
|
||||
title
|
||||
), level = logging_level)
|
||||
tree_items = list(tree.items())
|
||||
for key, value in tree_items[:-1]:
|
||||
log_tree(key, value, finals = finals + [False], log_leaves_types = log_leaves_types, logging_level = logging_level)
|
||||
for key, value in tree_items[-1:]:
|
||||
log_tree(key, value, finals = finals + [True], log_leaves_types = log_leaves_types, logging_level = logging_level)
|
||||
|
||||
# like logging.CRITICAl, logging.DEBUG etc
|
||||
FATAL = 60
|
||||
|
||||
def perror(s: Union[str, Any], e: Exception, logging_level: int = logging.ERROR):
|
||||
strerror = e.strerror if (isinstance(e, OSError) and e.strerror is not None) else e.__class__.__name__
|
||||
msg = f"{s}{': ' if s else ''}{strerror}"
|
||||
if logging_level == FATAL:
|
||||
logging_fatal(msg)
|
||||
else:
|
||||
logging.log(logging_level, msg)
|
||||
Reference in New Issue
Block a user