Skip to content

Instantly share code, notes, and snippets.

@josemarcosrf
Last active November 18, 2022 18:52
Show Gist options
  • Save josemarcosrf/0fb68e6a9a65353a9320b2f19f8c0bcc to your computer and use it in GitHub Desktop.
Save josemarcosrf/0fb68e6a9a65353a9320b2f19f8c0bcc to your computer and use it in GitHub Desktop.
Python logging coloredlogs styling utility functions
import sys
import os
from loguru import logger
from tqdm.auto import tqdm
from functools import partialmethod
class TqdmStream(object):
@classmethod
def write(_, msg):
tqdm.write(msg, file=sys.stderr, end="")
@classmethod
def flush(_):
sys.stderr.flush()
def logging_func():
logger.debug("debug")
logger.info("info")
logger.notice("notice")
logger.warning("warning")
logger.error("error")
def init_logger(
logger,
level,
fmt: str = None,
logdir: str = None,
filename: str = None,
rotation_minutes: int = 1,
retention_days: int = 14,
serialize: bool = False,
):
default_fmt = (
"<dim>{time:YYYY-MM-DD HH:mm:ss}</dim> <level>{level:<8}</level> | "
"<blue>{name:^15}:{function:^15}:{line:>3}</blue> - {message}"
)
_fmt = fmt or default_fmt
# if not TqdmStream, we should use: 'sys.stderr'
handlers = [
{"sink": TqdmStream(), "format": _fmt, "colorize": True, "level": level},
]
# logging to file
if logdir and filename:
handlers.append(
{
"sink": os.path.join(logdir, filename),
"rotation": f"{rotation_minutes} minute",
"retention": f"{retention_days} days",
"serialize": serialize,
}
)
config = {"handlers": handlers}
logger.configure(**config)
# Add a 'NOTICE' level
logger.level("NOTICE", no=25, icon="🤖", color="<cyan><bold>")
logger.__class__.notice = partialmethod(logger.__class__.log, "NOTICE")
if __name__ == "__main__":
import time
init_logger(logger, "DEBUG")
levels = ["DEBUG", "INFO", "NOTICE", "WARNING", "ERROR"]
for i in tqdm(range(10)):
logger.log(levels[i % 5], f"Ahhhhh... {i}")
time.sleep(0.2)
def install_logger(
logger, level, fmt="%(levelname)-8s %(name)-25s:%(lineno)4d - %(message)-50s"
):
""" Configures the given logger; format, logging level, style, etc """
import coloredlogs
# More style info at:
# https://coloredlogs.readthedocs.io/en/latest/api.html
field_styles = coloredlogs.DEFAULT_FIELD_STYLES.copy()
field_styles["asctime"] = {}
level_styles = coloredlogs.DEFAULT_LEVEL_STYLES.copy()
level_styles["debug"] = {"color": "white", "faint": True}
level_styles["notice"] = {"color": "cyan", "bold": True}
coloredlogs.install(
logger=logger,
level=level,
use_chroot=False,
fmt=fmt,
level_styles=level_styles,
field_styles=field_styles,
)
def add_new_level():
""" Creates a new 'notice' logging level """
# inspired by:
# https://stackoverflow.com/questions/2183233/how-to-add-a-custom-loglevel-to-pythons-logging-facility
NOTICE_LEVEL_NUM = 25
logging.addLevelName(NOTICE_LEVEL_NUM, "NOTICE")
def notice(self, message, *args, **kws):
if self.isEnabledFor(NOTICE_LEVEL_NUM):
self._log(NOTICE_LEVEL_NUM, message, args, **kws)
logging.Logger.notice = notice
@josemarcosrf
Copy link
Author

When using loguru with uvicorn you might want to override uvicorn's default logger, this gist shows how

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment