|
"""
|
|
Enhanced Logger with Colors and Emojis
|
|
Provides visual feedback for different log levels
|
|
"""
|
|
|
|
import logging
|
|
import sys
|
|
from typing import Any
|
|
|
|
class ColoredFormatter(logging.Formatter):
|
|
"""Custom formatter with colors and emojis"""
|
|
|
|
|
|
COLORS = {
|
|
'DEBUG': '\033[95m',
|
|
'INFO': '\033[94m',
|
|
'WARNING': '\033[93m',
|
|
'ERROR': '\033[91m',
|
|
'CRITICAL': '\033[91m',
|
|
'SUCCESS': '\033[92m',
|
|
'RESET': '\033[0m'
|
|
}
|
|
|
|
|
|
EMOJIS = {
|
|
'DEBUG': 'π£',
|
|
'INFO': 'π΅',
|
|
'WARNING': 'π‘',
|
|
'ERROR': 'π΄',
|
|
'CRITICAL': 'π΄',
|
|
'SUCCESS': 'π’'
|
|
}
|
|
|
|
def format(self, record):
|
|
|
|
level_name = record.levelname
|
|
color = self.COLORS.get(level_name, self.COLORS['RESET'])
|
|
emoji = self.EMOJIS.get(level_name, 'βͺ')
|
|
reset = self.COLORS['RESET']
|
|
|
|
|
|
log_message = super().format(record)
|
|
|
|
|
|
colored_message = f"{color}{emoji} {log_message}{reset}"
|
|
|
|
return colored_message
|
|
|
|
class EnhancedLogger:
|
|
"""Enhanced logger with custom methods"""
|
|
|
|
def __init__(self, name: str):
|
|
self.logger = logging.getLogger(name)
|
|
self.logger.setLevel(logging.DEBUG)
|
|
|
|
|
|
for handler in self.logger.handlers[:]:
|
|
self.logger.removeHandler(handler)
|
|
|
|
|
|
console_handler = logging.StreamHandler(sys.stdout)
|
|
console_handler.setLevel(logging.DEBUG)
|
|
|
|
|
|
formatter = ColoredFormatter(
|
|
'%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
|
datefmt='%H:%M:%S'
|
|
)
|
|
console_handler.setFormatter(formatter)
|
|
|
|
|
|
self.logger.addHandler(console_handler)
|
|
|
|
|
|
self.logger.propagate = False
|
|
|
|
def debug(self, message: str, **kwargs):
|
|
"""Log debug message"""
|
|
self.logger.debug(message, **kwargs)
|
|
|
|
def info(self, message: str, **kwargs):
|
|
"""Log info message"""
|
|
self.logger.info(message, **kwargs)
|
|
|
|
def warning(self, message: str, **kwargs):
|
|
"""Log warning message"""
|
|
self.logger.warning(message, **kwargs)
|
|
|
|
def error(self, message: str, **kwargs):
|
|
"""Log error message"""
|
|
self.logger.error(message, **kwargs)
|
|
|
|
def critical(self, message: str, **kwargs):
|
|
"""Log critical message"""
|
|
self.logger.critical(message, **kwargs)
|
|
|
|
def success(self, message: str, **kwargs):
|
|
"""Log success message (custom level)"""
|
|
|
|
record = self.logger.makeRecord(
|
|
self.logger.name, 25, '', 0, message, (), None
|
|
)
|
|
record.levelname = 'SUCCESS'
|
|
self.logger.handle(record)
|
|
|
|
def log_api_attempt(self, api_name: str, endpoint: str = ""):
|
|
"""Log API connection attempt"""
|
|
self.info(f"π Attempting to connect to {api_name} API {endpoint}")
|
|
|
|
def log_api_success(self, api_name: str, details: str = ""):
|
|
"""Log successful API connection"""
|
|
self.success(f"β
{api_name} API connected successfully {details}")
|
|
|
|
def log_api_failure(self, api_name: str, error: str):
|
|
"""Log API connection failure"""
|
|
self.error(f"β {api_name} API failed: {error}")
|
|
|
|
def log_data_collection(self, source: str, count: int):
|
|
"""Log data collection results"""
|
|
if count > 0:
|
|
self.success(f"π Collected {count} items from {source}")
|
|
else:
|
|
self.warning(f"π No data collected from {source}")
|
|
|
|
def log_processing_step(self, step: str, status: str = "started"):
|
|
"""Log processing steps"""
|
|
if status == "started":
|
|
self.info(f"βοΈ {step} - Started")
|
|
elif status == "completed":
|
|
self.success(f"βοΈ {step} - Completed")
|
|
elif status == "failed":
|
|
self.error(f"βοΈ {step} - Failed")
|
|
|
|
def log_validation_score(self, score: float, max_score: float = 10.0):
|
|
"""Log validation score with appropriate emoji"""
|
|
percentage = (score / max_score) * 100
|
|
|
|
if percentage >= 80:
|
|
emoji = "π"
|
|
level = "success"
|
|
elif percentage >= 60:
|
|
emoji = "π"
|
|
level = "info"
|
|
elif percentage >= 40:
|
|
emoji = "β οΈ"
|
|
level = "warning"
|
|
else:
|
|
emoji = "β"
|
|
level = "error"
|
|
|
|
message = f"{emoji} Validation Score: {score:.2f}/{max_score} ({percentage:.1f}%)"
|
|
|
|
if level == "success":
|
|
self.success(message)
|
|
elif level == "info":
|
|
self.info(message)
|
|
elif level == "warning":
|
|
self.warning(message)
|
|
else:
|
|
self.error(message)
|
|
|
|
def get_logger(name: str) -> EnhancedLogger:
|
|
"""Get an enhanced logger instance"""
|
|
return EnhancedLogger(name)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
logger = get_logger("test")
|
|
|
|
logger.debug("This is a debug message")
|
|
logger.info("This is an info message")
|
|
logger.warning("This is a warning message")
|
|
logger.error("This is an error message")
|
|
logger.success("This is a success message")
|
|
|
|
logger.log_api_attempt("Reddit", "/api/search")
|
|
logger.log_api_success("Reddit", "- 50 posts retrieved")
|
|
logger.log_api_failure("NewsAPI", "Invalid API key")
|
|
|
|
logger.log_data_collection("App Store", 25)
|
|
logger.log_data_collection("Reddit", 0)
|
|
|
|
logger.log_processing_step("Sentiment Analysis", "started")
|
|
logger.log_processing_step("Sentiment Analysis", "completed")
|
|
|
|
logger.log_validation_score(8.5)
|
|
logger.log_validation_score(3.2)
|
|
|