11import logging
22
33
4+ # ---- FORMATTING ----
5+
46class ColoredFormatter (logging .Formatter ):
57 """Custom formatter with colored output and specific formatting for transfers."""
68
@@ -59,12 +61,13 @@ def format(self, record: logging.LogRecord) -> str:
5961
6062 return result + exc_text
6163
62-
6364class HealthCheckFilter (logging .Filter ):
6465 def filter (self , record ):
6566 return '"GET /health HTTP/1.1" 200' not in record .getMessage ()
6667
6768
69+ # ---- LOGGING SETUP ----
70+
6871def setup_logging () -> logging .Logger :
6972 """Configure all loggers to use our custom ColoredFormatter."""
7073 formatter = ColoredFormatter (
@@ -96,7 +99,6 @@ def setup_logging() -> logging.Logger:
9699
97100 return root_logger
98101
99-
100102def get_logger (logger_name : str ) -> logging .Logger :
101103 console_handler = logging .StreamHandler ()
102104 console_handler .setLevel (logging .DEBUG )
@@ -114,3 +116,38 @@ def get_logger(logger_name: str) -> logging.Logger:
114116 logger .propagate = False
115117
116118 return logger
119+
120+
121+ # ---- PATCHING ----
122+
123+ class HasLogging (type ):
124+ """Metaclass that automatically adds logging methods and a logger property."""
125+
126+ def __new__ (mcs , name , bases , namespace , ** kwargs ):
127+ name_from = kwargs .get ('name_from' , 'name' )
128+
129+ @property
130+ def logger (self ):
131+ if not hasattr (self , '_logger' ):
132+ class_name = self .__class__ .__name__
133+ fallback_name = class_name + str (id (self ))[- 4 :]
134+ logger_name = getattr (self , name_from , fallback_name )
135+ self ._logger = get_logger (logger_name )
136+ if not hasattr (self , name_from ):
137+ self ._logger .warning (
138+ f"Object { class_name } does not have attribute '{ name_from } ', "
139+ f"using default name: { logger_name } "
140+ )
141+ return self ._logger
142+
143+ namespace ['logger' ] = logger
144+
145+ def make_log_method (level ):
146+ def log_method (self , msg , * args , ** kwargs ):
147+ getattr (self .logger , level )(msg , * args , ** kwargs )
148+ return log_method
149+
150+ for level in {'debug' , 'info' , 'warning' , 'error' , 'exception' , 'critical' }:
151+ namespace [level ] = make_log_method (level )
152+
153+ return super ().__new__ (mcs , name , bases , namespace )
0 commit comments