Initial commit

This commit is contained in:
2025-07-11 13:52:19 +00:00
commit e0c489f625
362 changed files with 27286 additions and 0 deletions
+174
View File
@@ -0,0 +1,174 @@
import os
import sys
import logging
import datetime
import pytest
from dotenv import load_dotenv, find_dotenv
# Load environment variables
load_dotenv(find_dotenv())
# Define a global format string for log alignment
LOG_FORMAT = "%(asctime)s %(levelname)-8s: %(filename)-20s:%(funcName)-20s:%(lineno)-4d >>> %(message)s"
# Define custom logging levels
SUCCESS_LOG_LEVEL = 21
APP_LOG_LEVEL = 15
PROD_LOG_LEVEL = 14
DATABASE_LOG_LEVEL = 13
CHAT_LOG_LEVEL = 12
QUERY_LOG_LEVEL = 11
TESTING_LOG_LEVEL = 9
VARIABLES_LOG_LEVEL = 2
PEDANTIC_LOG_LEVEL = 1
# Register custom log levels
CUSTOM_LEVELS = {
SUCCESS_LOG_LEVEL: "SUCCESS",
APP_LOG_LEVEL: "APP",
PROD_LOG_LEVEL: "PROD",
DATABASE_LOG_LEVEL: "DATABASE",
CHAT_LOG_LEVEL: "CHAT",
QUERY_LOG_LEVEL: "QUERY",
TESTING_LOG_LEVEL: "TESTING",
VARIABLES_LOG_LEVEL: "VARIABLES",
PEDANTIC_LOG_LEVEL: "PEDANTIC"
}
for level, name in CUSTOM_LEVELS.items():
logging.addLevelName(level, name)
# ANSI escape sequences for colors
class LogColors:
"""ANSI escape sequences for various log levels to colorize log output."""
DARK_RED, BRIGHT_RED = '\033[31m', '\033[91m'
ORANGE, GOLD, YELLOW = '\033[33m', '\033[93m', '\033[93m'
GREEN, DARKGREEN, LIGHTGREEN = '\033[92m', '\033[32m', '\033[92m'
LIGHTBLUE, BLUE, INDIGO, VIOLET = '\033[94m', '\033[94m', '\033[34m', '\033[35m'
RESET, WHITE, BLACK = '\033[0m', '\033[37m', '\033[30m'
# Custom Formatter
class ColoredFormatter(logging.Formatter):
"""Custom formatter to add color and emojis to log messages for console output."""
COLORS = {
logging.CRITICAL: f"{LogColors.DARK_RED}🚨 ",
logging.ERROR: f"{LogColors.BRIGHT_RED}",
logging.WARNING: f"{LogColors.ORANGE}⚠️ ",
logging.INFO: f"{LogColors.GREEN}",
logging.DEBUG: f"{LogColors.BLUE}🐛 ",
SUCCESS_LOG_LEVEL: f"{LogColors.LIGHTGREEN}",
APP_LOG_LEVEL: f"{LogColors.INDIGO}🚀 ",
PROD_LOG_LEVEL: f"{LogColors.VIOLET}🏭 ",
DATABASE_LOG_LEVEL: f"{LogColors.DARKGREEN}🗄️ ",
CHAT_LOG_LEVEL: f"{LogColors.LIGHTBLUE}💬 ",
QUERY_LOG_LEVEL: f"{LogColors.GOLD}🔍 ",
TESTING_LOG_LEVEL: f"{LogColors.YELLOW}🧪 ",
VARIABLES_LOG_LEVEL: f"{LogColors.WHITE}🔢 ",
PEDANTIC_LOG_LEVEL: f"{LogColors.BLACK}🔬 ",
}
def format(self, record):
log_fmt = self.COLORS.get(record.levelno, self.COLORS[logging.INFO]) + self._fmt
formatter = logging.Formatter(log_fmt)
message = formatter.format(record) + LogColors.RESET
try:
return message
except UnicodeEncodeError:
return message.encode('ascii', 'replace').decode('ascii')
def formatException(self, ei):
try:
return super().formatException(ei)
except UnicodeEncodeError:
return super().formatException(ei).encode('ascii', 'replace').decode('ascii')
class FileFormatter(logging.Formatter):
def format(self, record):
return logging.Formatter(LOG_FORMAT).format(record)
class PytestFormatter:
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(self, item, call):
outcome = yield
report = outcome.get_result()
if report.when == "call":
if report.passed:
logging.success(f"✅ Test passed: {item.name}")
elif report.failed:
logging.error(f"❌ Test failed: {item.name}")
elif report.skipped:
logging.warning(f"⏭️ Test skipped: {item.name}")
# Custom logger methods
def _add_custom_log_methods():
def create_log_method(level):
def log_method(self, message, *args, **kws):
if self.isEnabledFor(level):
self._log(level, message, args, **kws)
return log_method
custom_methods = {
"chat": CHAT_LOG_LEVEL, "variables": VARIABLES_LOG_LEVEL,
"pedantic": PEDANTIC_LOG_LEVEL, "prod": PROD_LOG_LEVEL,
"query": QUERY_LOG_LEVEL, "database": DATABASE_LOG_LEVEL,
"testing": TESTING_LOG_LEVEL, "app": APP_LOG_LEVEL, "success": SUCCESS_LOG_LEVEL
}
for method_name, level in custom_methods.items():
setattr(logging.Logger, method_name, create_log_method(level))
_add_custom_log_methods()
# Set an environment directory
def set_log_path(env_var):
env_path = os.getenv(env_var.upper())
if env_path and not os.path.exists(env_path):
os.makedirs(env_path)
return env_path
# Get a logger with specified settings
def get_logger(name=None, log_level=None, log_path=None, log_file=None, delimiter='_', runtime=False, log_format=None):
logger = logging.getLogger(name or __name__)
log_levels = {
'CRITICAL': logging.CRITICAL, 'ERROR': logging.ERROR, 'WARNING': logging.WARNING,
'SUCCESS': SUCCESS_LOG_LEVEL, 'APP': APP_LOG_LEVEL, 'PROD': PROD_LOG_LEVEL,
'DATABASE': DATABASE_LOG_LEVEL, 'INFO': logging.INFO, 'DEBUG': logging.DEBUG,
'TESTING': TESTING_LOG_LEVEL, 'CHAT': CHAT_LOG_LEVEL, 'QUERY': QUERY_LOG_LEVEL,
'VARIABLES': VARIABLES_LOG_LEVEL, 'PEDANTIC': PEDANTIC_LOG_LEVEL,
}
desired_level = log_levels.get(log_level, logging.INFO) if log_level else logger.level or logging.INFO
logger.setLevel(desired_level)
logger.propagate = False
console_formatter = ColoredFormatter(LOG_FORMAT if log_format in (None, "default") else log_format)
file_formatter = FileFormatter(LOG_FORMAT if log_format in (None, "default") else log_format)
if not logger.handlers:
if runtime:
ch = logging.StreamHandler(sys.stdout)
ch.setLevel(logging.DEBUG)
ch.setFormatter(console_formatter)
logger.addHandler(ch)
if log_path and log_file:
os.makedirs(log_path, exist_ok=True)
log_file_path = os.path.join(log_path, f"{log_file}{'_' if runtime else delimiter}{datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S') if not runtime else ''}.log")
fh = logging.FileHandler(log_file_path)
fh.setLevel(desired_level)
fh.setFormatter(file_formatter)
logger.addHandler(fh)
else:
for handler in logger.handlers:
handler.setLevel(desired_level)
handler.setFormatter(file_formatter if isinstance(handler, logging.FileHandler) else console_formatter)
return logger
# Retrieve all loggers
def get_loggers():
"""Return a list of all logger instances."""
return [logging.getLogger(name) for name in logging.Logger.manager.loggerDict]
# Initialize logger using provided settings
def initialise_logger(log_name='backend', log_level=None, log_dir=None, log_format='default', runtime=True):
log_level = log_level or os.getenv("LOG_LEVEL", "DEBUG")
log_dir = log_dir or os.getenv("LOG_PATH", "/logs")
return get_logger(name=log_name, log_level=log_level, log_path=log_dir, log_file=log_name, runtime=runtime, log_format=log_format)