Configurable logger with file, console, and WandB backends. Example config:: logger = dict( type='Logger', level='INFO', log_file='logs/run.log', console=True, wandb=dict(enabled=True, project='datastudio', name='exp_1'),
| 61 | |
| 62 | @HOOKS.register_module() |
| 63 | class Logger: |
| 64 | """Configurable logger with file, console, and WandB backends. |
| 65 | |
| 66 | Example config:: |
| 67 | |
| 68 | logger = dict( |
| 69 | type='Logger', |
| 70 | level='INFO', |
| 71 | log_file='logs/run.log', |
| 72 | console=True, |
| 73 | wandb=dict(enabled=True, project='datastudio', name='exp_1'), |
| 74 | ) |
| 75 | """ |
| 76 | |
| 77 | _instance: Optional["Logger"] = None |
| 78 | |
| 79 | def __init__( |
| 80 | self, |
| 81 | name: str = "datastudio", |
| 82 | level: Union[str, int] = "INFO", |
| 83 | log_file: Optional[str] = None, |
| 84 | console: bool = True, |
| 85 | colored: bool = True, |
| 86 | work_dir: Optional[str] = None, |
| 87 | wandb_config: Optional[Dict] = None, |
| 88 | timestamp: bool = True, |
| 89 | **kwargs, |
| 90 | ): |
| 91 | self.name = name |
| 92 | self._logger = logging.getLogger(name) |
| 93 | self._logger.setLevel( |
| 94 | getattr(logging, level.upper()) if isinstance(level, str) else level |
| 95 | ) |
| 96 | self._logger.handlers.clear() |
| 97 | |
| 98 | self.work_dir = work_dir or os.getcwd() |
| 99 | self._wandb_enabled = False |
| 100 | |
| 101 | # Console handler |
| 102 | if console: |
| 103 | console_handler = logging.StreamHandler(sys.stdout) |
| 104 | console_handler.setLevel(self._logger.level) |
| 105 | fmt = "%(asctime)s %(levelname)s %(message)s" |
| 106 | datefmt = "%Y-%m-%d %H:%M:%S" |
| 107 | formatter = ColoredFormatter(fmt, datefmt, use_color=colored) |
| 108 | console_handler.setFormatter(formatter) |
| 109 | self._logger.addHandler(console_handler) |
| 110 | |
| 111 | # File handler |
| 112 | if log_file: |
| 113 | # Add timestamp to log filename if enabled |
| 114 | if timestamp: |
| 115 | log_file = self._add_timestamp_to_filename(log_file) |
| 116 | |
| 117 | log_path = ( |
| 118 | log_file |
| 119 | if os.path.isabs(log_file) |
| 120 | else os.path.join(self.work_dir, log_file) |
no outgoing calls