File size: 6,359 Bytes
72f802a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
"""
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"""
# ANSI color codes
COLORS = {
'DEBUG': '\033[95m', # Purple
'INFO': '\033[94m', # Blue
'WARNING': '\033[93m', # Yellow
'ERROR': '\033[91m', # Red
'CRITICAL': '\033[91m', # Red
'SUCCESS': '\033[92m', # Green
'RESET': '\033[0m' # Reset
}
# Emojis for different levels
EMOJIS = {
'DEBUG': 'π£',
'INFO': 'π΅',
'WARNING': 'π‘',
'ERROR': 'π΄',
'CRITICAL': 'π΄',
'SUCCESS': 'π’'
}
def format(self, record):
# Get color and emoji for log level
level_name = record.levelname
color = self.COLORS.get(level_name, self.COLORS['RESET'])
emoji = self.EMOJIS.get(level_name, 'βͺ')
reset = self.COLORS['RESET']
# Format the message
log_message = super().format(record)
# Add color and emoji
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)
# Remove existing handlers to avoid duplicates
for handler in self.logger.handlers[:]:
self.logger.removeHandler(handler)
# Create console handler
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setLevel(logging.DEBUG)
# Create formatter
formatter = ColoredFormatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s',
datefmt='%H:%M:%S'
)
console_handler.setFormatter(formatter)
# Add handler to logger
self.logger.addHandler(console_handler)
# Prevent propagation to avoid duplicate logs
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)"""
# Create a custom log record for success
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)
# Example usage
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)
|