code: def get_logger(
      name, log_file=None, log_level=logging.INFO, file_mode="w"
  ):
      """Initialize and get a logger by name.
      If the logger has not been initialized, this method will initialize the
      logger by adding one or two handlers, otherwise the initialized logger will
      be directly returned. During initialization, a StreamHandler will always be
      added. If `log_file` is specified and the process rank is 0, a FileHandler
      will also be added.
      Args:
          name (str): Logger name.
          log_file (str | None): The log filename. If specified, a FileHandler
              will be added to the logger.
          log_level (int): The logger level. Note that only the process of
              rank 0 is affected, and other processes will set the level to
              "Error" thus be silent most of the time.
          file_mode (str): The file mode used in opening log file.
              Defaults to 'w'.
      Returns:
          logging.Logger: The expected logger.
      """
      logger = logging.getLogger(name)
      if name in logger_initialized:
          return logger
      # handle hierarchical names
      # e.g., logger "a" is initialized, then logger "a.b" will skip the
      # initialization since it is a child of "a".
      for logger_name in logger_initialized:
          if name.startswith(logger_name):
              return logger
  
      # handle duplicate logs to the console
      # Starting in 1.8.0, PyTorch DDP attaches a StreamHandler <stderr> (NOTSET)
      # to the root logger. As logger.propagate is True by default, this root
      # level handler causes logging messages from rank>0 processes to
      # unexpectedly show up on the console, creating much unwanted clutter.
      # To fix this issue, we set the root logger's StreamHandler, if any, to log
      # at the ERROR level.
      for handler in logger.root.handlers:
          if type(handler) is logging.StreamHandler:
              handler.setLevel(logging.ERROR)
  
      stream_handler = logging.StreamHandler()
      handlers = [stream_handler]
  
      if dist.is_available() and dist.is_initialized():
          rank = dist.get_rank()
      else:
          rank = 0
  
      # only rank 0 will add a FileHandler
      if rank == 0 and log_file is not None:
          # Here, the default behaviour of the official logger is 'a'. Thus, we
          # provide an interface to change the file mode to the default
          # behaviour.
          file_handler = logging.FileHandler(log_file, file_mode)
          handlers.append(file_handler)
  
      formatter = logging.Formatter(
          "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
      )
      for handler in handlers:
          handler.setFormatter(formatter)
          handler.setLevel(log_level)
          logger.addHandler(handler)
  
      if rank == 0:
          logger.setLevel(log_level)
      else:
          logger.setLevel(logging.ERROR)
  
      logger_initialized[name] = True
  
      return logger
  
file_path: insightface/parsing/dml_csr/utils/logging.py
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import logging
  import torch.distributed
label_desc: Use image node_id 2 for calling a global function with example usage: get_logger(name, log_file, log_level, file_mode) and returns: logger, logger, logger