Get logging logger Args: log_file: Log filename, if specified, file handler will be added to logger log_level: Logging level. file_mode: Specifies the mode to open the file, if filename is specified (if filemode is unspecified, it defaults to 'w'
(log_file: Optional[str] = None, log_level: Optional[int] = None, file_mode: str = 'w')
| 53 | |
| 54 | |
| 55 | def get_logger(log_file: Optional[str] = None, log_level: Optional[int] = None, file_mode: str = 'w'): |
| 56 | """ Get logging logger |
| 57 | |
| 58 | Args: |
| 59 | log_file: Log filename, if specified, file handler will be added to |
| 60 | logger |
| 61 | log_level: Logging level. |
| 62 | file_mode: Specifies the mode to open the file, if filename is |
| 63 | specified (if filemode is unspecified, it defaults to 'w'). |
| 64 | """ |
| 65 | if log_level is None: |
| 66 | log_level = os.getenv('LOG_LEVEL', 'INFO').upper() |
| 67 | log_level = getattr(logging, log_level, logging.INFO) |
| 68 | logger_name = __name__.split('.')[0] |
| 69 | logger = logging.getLogger(logger_name) |
| 70 | logger.propagate = False |
| 71 | if logger_name in init_loggers: |
| 72 | add_file_handler_if_needed(logger, log_file, file_mode, log_level) |
| 73 | return logger |
| 74 | |
| 75 | # handle duplicate logs to the console |
| 76 | # Starting in 1.8.0, PyTorch DDP attaches a StreamHandler <stderr> (NOTSET) |
| 77 | # to the root logger. As logger.propagate is True by default, this root |
| 78 | # level handler causes logging messages from rank>0 processes to |
| 79 | # unexpectedly show up on the console, creating much unwanted clutter. |
| 80 | # To fix this issue, we set the root logger's StreamHandler, if any, to log |
| 81 | # at the ERROR level. |
| 82 | for handler in logger.root.handlers: |
| 83 | if type(handler) is logging.StreamHandler: |
| 84 | handler.setLevel(logging.ERROR) |
| 85 | |
| 86 | stream_handler = logging.StreamHandler() |
| 87 | handlers = [stream_handler] |
| 88 | |
| 89 | is_worker0 = _is_local_master() |
| 90 | |
| 91 | if is_worker0 and log_file is not None: |
| 92 | file_handler = logging.FileHandler(log_file, file_mode) |
| 93 | handlers.append(file_handler) |
| 94 | |
| 95 | for handler in handlers: |
| 96 | handler.setFormatter(logger_format) |
| 97 | handler.setLevel(log_level) |
| 98 | logger.addHandler(handler) |
| 99 | |
| 100 | if is_worker0: |
| 101 | logger.setLevel(log_level) |
| 102 | else: |
| 103 | logger.setLevel(logging.ERROR) |
| 104 | |
| 105 | init_loggers[logger_name] = True |
| 106 | |
| 107 | logger.info_once = MethodType(info_once, logger) |
| 108 | logger.warning_once = MethodType(warning_once, logger) |
| 109 | logger.info_if = MethodType(info_if, logger) |
| 110 | logger.warning_if = MethodType(warning_if, logger) |
| 111 | return logger |
| 112 |