parameters: (output=None, name="hapi", log_level=logging.INFO)
return_statement: return logger
docstring: Initialize logger of hapi and set its verbosity level to "INFO".
  
      Args:
          output (str): a file name or a directory to save log. If None, will not save log file.
              If ends with ".txt" or ".log", assumed to be a file name.
              Otherwise, logs will be saved to `output/log.txt`.
          name (str): the root module name of this logger. Default: 'hapi'.
          log_level (enum): log level. eg.'INFO', 'DEBUG', 'ERROR'. Default: logging.INFO.
      Returns:
          logging.Logger: a logger
docstring_summary: Initialize logger of hapi and set its verbosity level to "INFO".
docstring_tokens: Initialize logger of hapi and set its verbosity level to INFO .
function: def setup_logger(output=None, name="hapi", log_level=logging.INFO):
      """
      Initialize logger of hapi and set its verbosity level to "INFO".
  
      Args:
          output (str): a file name or a directory to save log. If None, will not save log file.
              If ends with ".txt" or ".log", assumed to be a file name.
              Otherwise, logs will be saved to `output/log.txt`.
          name (str): the root module name of this logger. Default: 'hapi'.
          log_level (enum): log level. eg.'INFO', 'DEBUG', 'ERROR'. Default: logging.INFO.
      Returns:
          logging.Logger: a logger
      """
      logger = logging.getLogger(name)
      logger.propagate = False
      logger.setLevel(log_level)
  
      format_str = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
      # stdout logging: only local rank==0
      local_rank = ParallelEnv().local_rank
      if local_rank == 0 and len(logger.handlers) == 0:
          ch = logging.StreamHandler(stream=sys.stdout)
          ch.setLevel(log_level)
  
          ch.setFormatter(logging.Formatter(format_str))
          logger.addHandler(ch)
  
      # file logging if output is not None: all workers
      if output is not None:
          if output.endswith(".txt") or output.endswith(".log"):
              filename = output
          else:
              filename = os.path.join(output, "log.txt")
  
          if local_rank > 0:
              filename = filename + ".rank{}".format(local_rank)
  
          if not os.path.exists(os.path.dirname(filename)):
              os.makedirs(os.path.dirname(filename))
  
          fh = logging.StreamHandler(filename)
          fh.setLevel(log_level)
          fh.setFormatter(logging.Formatter(format_str))
          logger.addHandler(fh)
  
      return logger
function_tokens: def setup_logger ( output = None , name = "hapi" , log_level = logging . INFO ) : logger = logging . getLogger ( name ) logger . propagate = False logger . setLevel ( log_level ) format_str = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' # stdout logging: only local rank==0 local_rank = ParallelEnv ( ) . local_rank if local_rank == 0 and len ( logger . handlers ) == 0 : ch = logging . StreamHandler ( stream = sys . stdout ) ch . setLevel ( log_level ) ch . setFormatter ( logging . Formatter ( format_str ) ) logger . addHandler ( ch ) # file logging if output is not None: all workers if output is not None : if output . endswith ( ".txt" ) or output . endswith ( ".log" ) : filename = output else : filename = os . path . join ( output , "log.txt" ) if local_rank > 0 : filename = filename + ".rank{}" . format ( local_rank ) if not os . path . exists ( os . path . dirname ( filename ) ) : os . makedirs ( os . path . dirname ( filename ) ) fh = logging . StreamHandler ( filename ) fh . setLevel ( log_level ) fh . setFormatter ( logging . Formatter ( format_str ) ) logger . addHandler ( fh ) return logger