⚠️ DEPRECATE: This project has been deprecated since loguru has most of the features that haplog originally intended to develop.
Happy logging guys :)
Provides enhancements for logging
functionality, including:
- Color the texts of
logging
:
|
# https://talyian.github.io/ansicolors/ |
|
|
|
# black = "\x1b[30;20m" |
|
red = "\x1b[31;20m" |
|
bold_red = "\x1b[31;1m" |
|
green = "\x1b[32;20m" |
|
yellow = "\x1b[33;20m" |
|
# blue = "\x1b[34;20m" |
|
# magenta = "\x1b[35;20m" |
|
# cyan = "\x1b[36;20m" |
|
# white = "\x1b[37;20m" |
|
grey = "\x1b[38;20m" |
|
|
|
# \x1b[38;2;r;g;bm - foreground |
|
# \x1b[48;2;r;g;bm - background |
|
|
|
reset = "\x1b[0m" |
|
|
|
self.formats = { |
|
logging.DEBUG: grey + costom_format + reset, |
|
logging.INFO: green + costom_format + reset, |
|
logging.WARNING: yellow + costom_format + reset, |
|
logging.ERROR: red + costom_format + reset, |
|
logging.CRITICAL: bold_red + costom_format + reset, |
|
} |
- Redirect the standard output of third-party modules to log records, which is usually used when developers are unwilling to spend time manually changing
print()
to the corresponding logging
function.
|
class OutputLogger: |
|
""" |
|
serves as a pseudo file-like stream object that redirects written content to a logger instance. |
|
It overrides the `write` method to append the written messages to an internal buffer |
|
(`linebuf`). When a message ends with a newline character, it logs the buffered messages |
|
as a log record. |
|
""" |
|
with redirect_stdout( |
|
OutputLogger(logger_name=LOGGER_NAME, logging_level=logging.DEBUG) # type: ignore |
|
): |
|
print(MESSAGE + " by print()") |
|
third_party_function() |
- Logging (of cource):
|
class MultiProcessLogger: |
|
""" |
|
Implements a custom logger designed for multi-process environments. |
|
It is based on the 'Logging Cookbook - Logging to a single file from multiple processes' example |
|
in the Python documentation. It utilizes a multiprocessing queue and a listener process to |
|
enable logging across multiple processes. The class provides functionality for logging records |
|
to a file and printing logs to the console. |
|
""" |
- single-process:
|
def single_process(): |
|
mpl = MultiProcessLogger(log_folder, level_console=logging.DEBUG) |
|
mpl.start() |
|
worker_configurer(mpl.queue) # type: ignore |
|
|
|
logger = logging.getLogger(LOGGER_NAME) |
|
|
|
with redirect_stdout( |
|
OutputLogger(logger_name=LOGGER_NAME, logging_level=logging.DEBUG) # type: ignore |
|
): |
|
print(MESSAGE + " by print()") |
|
third_party_function() |
|
|
|
logger.debug(MESSAGE) |
|
logger.info(MESSAGE) |
|
logger.warning(MESSAGE) |
|
logger.error(MESSAGE) |
|
logger.critical(MESSAGE) |
|
|
|
mpl.join() |
- multi-process:
|
def multi_process(): |
|
mpl = MultiProcessLogger(log_folder, level_console=logging.DEBUG) |
|
mpl.start() |
|
|
|
with concurrent.futures.ProcessPoolExecutor(max_workers=10) as executor: |
|
for _ in range(10): |
|
executor.submit(worker_process, mpl.queue, worker_configurer) |
|
|
|
mpl.join() |
pip install "https://github.com/changchiyou/haplog/archive/main.zip"
Download and execute /examples/demo_haplog.py
:
|
import concurrent.futures |
|
import logging |
|
import logging.handlers |
|
import multiprocessing |
|
from contextlib import redirect_stdout |
|
from pathlib import Path |
|
|
|
from haplog import MultiProcessLogger, OutputLogger, worker_configurer |
|
|
|
LOGGER_NAME = "test" |
|
MESSAGE = "test" |
|
|
|
log_folder = (Path(__file__).parent) / "logs" |
|
|
|
if log_folder.exists() is False: |
|
log_folder.mkdir() |
|
|
|
|
|
def third_party_function(): |
|
print(MESSAGE + " by third_party_function()") |
|
|
|
|
|
def single_process(): |
|
mpl = MultiProcessLogger(log_folder, level_console=logging.DEBUG) |
|
mpl.start() |
|
worker_configurer(mpl.queue) # type: ignore |
|
|
|
logger = logging.getLogger(LOGGER_NAME) |
|
|
|
with redirect_stdout( |
|
OutputLogger(logger_name=LOGGER_NAME, logging_level=logging.DEBUG) # type: ignore |
|
): |
|
print(MESSAGE + " by print()") |
|
third_party_function() |
|
|
|
logger.debug(MESSAGE) |
|
logger.info(MESSAGE) |
|
logger.warning(MESSAGE) |
|
logger.error(MESSAGE) |
|
logger.critical(MESSAGE) |
|
|
|
mpl.join() |
|
|
|
|
|
def worker_process(queue, configurer): |
|
import time |
|
from random import random |
|
|
|
configurer(queue) |
|
|
|
name = multiprocessing.current_process().name |
|
logger = logging.getLogger(name) |
|
logger.info("Worker started: %s" % name) |
|
time.sleep(random()) |
|
logger.info("Worker finished: %s" % name) |
|
|
|
|
|
def multi_process(): |
|
mpl = MultiProcessLogger(log_folder, level_console=logging.DEBUG) |
|
mpl.start() |
|
|
|
with concurrent.futures.ProcessPoolExecutor(max_workers=10) as executor: |
|
for _ in range(10): |
|
executor.submit(worker_process, mpl.queue, worker_configurer) |
|
|
|
mpl.join() |
|
|
|
|
|
if __name__ == "__main__": |
|
single_process() |
|
multi_process() |
Check ANSI Color Codes for more personalized color schemes.