33import logging
44import threading
55import time
6+ from dataclasses import dataclass
67from enum import Enum
78from typing import Dict , Optional , Tuple , Union
89from pythonLogs .basic_log import BasicLog
1213from pythonLogs .timed_rotating import TimedRotatingLog
1314
1415
16+ @dataclass
17+ class LoggerConfig :
18+ """Configuration class to group logger parameters"""
19+ level : Optional [Union [LogLevel , str ]] = None
20+ name : Optional [str ] = None
21+ directory : Optional [str ] = None
22+ filenames : Optional [list | tuple ] = None
23+ encoding : Optional [str ] = None
24+ datefmt : Optional [str ] = None
25+ timezone : Optional [str ] = None
26+ streamhandler : Optional [bool ] = None
27+ showlocation : Optional [bool ] = None
28+ maxmbytes : Optional [int ] = None
29+ when : Optional [Union [RotateWhen , str ]] = None
30+ sufix : Optional [str ] = None
31+ rotateatutc : Optional [bool ] = None
32+ daystokeep : Optional [int ] = None
33+
34+
1535class LoggerType (str , Enum ):
1636 """Available logger types"""
1737 BASIC = "basic"
@@ -80,7 +100,7 @@ def get_or_create_logger(
80100
81101 # Check if logger already exists in the registry
82102 if name in cls ._logger_registry :
83- logger , timestamp = cls ._logger_registry [name ]
103+ logger , _ = cls ._logger_registry [name ]
84104 # Update timestamp for LRU tracking
85105 cls ._logger_registry [name ] = (logger , time .time ())
86106 return logger
@@ -189,42 +209,17 @@ def get_registered_loggers(cls) -> dict[str, logging.Logger]:
189209 @staticmethod
190210 def create_logger (
191211 logger_type : Union [LoggerType , str ],
192- level : Optional [Union [LogLevel , str ]] = None ,
193- name : Optional [str ] = None ,
194- directory : Optional [str ] = None ,
195- filenames : Optional [list | tuple ] = None ,
196- encoding : Optional [str ] = None ,
197- datefmt : Optional [str ] = None ,
198- timezone : Optional [str ] = None ,
199- streamhandler : Optional [bool ] = None ,
200- showlocation : Optional [bool ] = None , # Size rotating specific
201- maxmbytes : Optional [int ] = None , # Timed rotating specific
202- when : Optional [Union [RotateWhen , str ]] = None ,
203- sufix : Optional [str ] = None ,
204- rotateatutc : Optional [bool ] = None ,
205- # Common
206- daystokeep : Optional [int ] = None ,
212+ config : Optional [LoggerConfig ] = None ,
213+ ** kwargs
207214 ) -> logging .Logger :
208215
209216 """
210217 Factory method to create loggers based on type.
211218
212219 Args:
213220 logger_type: Type of logger to create (LoggerType enum or string)
214- level: Log level (LogLevel enum or string: DEBUG, INFO, WARNING, ERROR, CRITICAL)
215- name: Logger name
216- directory: Log directory path
217- filenames: List/tuple of log filenames
218- encoding: File encoding
219- datefmt: Date format string
220- timezone: Timezone for timestamps
221- streamhandler: Enable console output
222- showlocation: Show file location in logs
223- maxmbytes: Max file size in MB (size rotating only)
224- when: When to rotate (RotateWhen enum or string: MIDNIGHT, HOURLY, DAILY, etc.)
225- sufix: Date suffix for rotated files (timed rotating only)
226- rotateatutc: Rotate at UTC time (timed rotating only)
227- daystokeep: Days to keep old logs
221+ config: LoggerConfig object with logger parameters
222+ **kwargs: Individual logger parameters (for backward compatibility)
228223
229224 Returns:
230225 Configured logger instance
@@ -239,50 +234,72 @@ def create_logger(
239234 except ValueError :
240235 raise ValueError (f"Invalid logger type: { logger_type } . Valid types: { [t .value for t in LoggerType ]} " )
241236
237+ # Merge config and kwargs (kwargs take precedence for backward compatibility)
238+ if config is None :
239+ config = LoggerConfig ()
240+
241+ # Create a new config with kwargs overriding config values
242+ final_config = LoggerConfig (
243+ level = kwargs .get ('level' , config .level ),
244+ name = kwargs .get ('name' , config .name ),
245+ directory = kwargs .get ('directory' , config .directory ),
246+ filenames = kwargs .get ('filenames' , config .filenames ),
247+ encoding = kwargs .get ('encoding' , config .encoding ),
248+ datefmt = kwargs .get ('datefmt' , config .datefmt ),
249+ timezone = kwargs .get ('timezone' , config .timezone ),
250+ streamhandler = kwargs .get ('streamhandler' , config .streamhandler ),
251+ showlocation = kwargs .get ('showlocation' , config .showlocation ),
252+ maxmbytes = kwargs .get ('maxmbytes' , config .maxmbytes ),
253+ when = kwargs .get ('when' , config .when ),
254+ sufix = kwargs .get ('sufix' , config .sufix ),
255+ rotateatutc = kwargs .get ('rotateatutc' , config .rotateatutc ),
256+ daystokeep = kwargs .get ('daystokeep' , config .daystokeep )
257+ )
258+
242259 # Convert enum values to strings for logger classes
243- level_str = level .value if isinstance (level , LogLevel ) else level
244- when_str = when .value if isinstance (when , RotateWhen ) else when
260+ level_str = final_config . level .value if isinstance (final_config . level , LogLevel ) else final_config . level
261+ when_str = final_config . when .value if isinstance (final_config . when , RotateWhen ) else final_config . when
245262
246263 # Create logger based on type
247264 match logger_type :
248265 case LoggerType .BASIC :
249266 logger_instance = BasicLog (
250267 level = level_str ,
251- name = name ,
252- encoding = encoding ,
253- datefmt = datefmt ,
254- timezone = timezone ,
255- showlocation = showlocation , )
268+ name = final_config . name ,
269+ encoding = final_config . encoding ,
270+ datefmt = final_config . datefmt ,
271+ timezone = final_config . timezone ,
272+ showlocation = final_config . showlocation , )
256273
257274 case LoggerType .SIZE_ROTATING :
258275 logger_instance = SizeRotatingLog (
259276 level = level_str ,
260- name = name ,
261- directory = directory ,
262- filenames = filenames ,
263- maxmbytes = maxmbytes ,
264- daystokeep = daystokeep ,
265- encoding = encoding ,
266- datefmt = datefmt ,
267- timezone = timezone ,
268- streamhandler = streamhandler ,
269- showlocation = showlocation , )
277+ name = final_config . name ,
278+ directory = final_config . directory ,
279+ filenames = final_config . filenames ,
280+ maxmbytes = final_config . maxmbytes ,
281+ daystokeep = final_config . daystokeep ,
282+ encoding = final_config . encoding ,
283+ datefmt = final_config . datefmt ,
284+ timezone = final_config . timezone ,
285+ streamhandler = final_config . streamhandler ,
286+ showlocation = final_config . showlocation , )
270287
271288 case LoggerType .TIMED_ROTATING :
272289 logger_instance = TimedRotatingLog (
273290 level = level_str ,
274- name = name ,
275- directory = directory ,
276- filenames = filenames ,
291+ name = final_config . name ,
292+ directory = final_config . directory ,
293+ filenames = final_config . filenames ,
277294 when = when_str ,
278- sufix = sufix ,
279- daystokeep = daystokeep ,
280- encoding = encoding ,
281- datefmt = datefmt ,
282- timezone = timezone ,
283- streamhandler = streamhandler ,
284- showlocation = showlocation ,
285- rotateatutc = rotateatutc , )
295+ sufix = final_config . sufix ,
296+ daystokeep = final_config . daystokeep ,
297+ encoding = final_config . encoding ,
298+ datefmt = final_config . datefmt ,
299+ timezone = final_config . timezone ,
300+ streamhandler = final_config . streamhandler ,
301+ showlocation = final_config . showlocation ,
302+ rotateatutc = final_config . rotateatutc , )
286303
287304 case _:
288305 raise ValueError (f"Unsupported logger type: { logger_type } " )
0 commit comments