class_docstr: Logger for Ray Datasets which writes logs to a separate log file
  at `DatasetLogger.DEFAULT_DATASET_LOG_PATH`. Can optionally turn off
  logging to stdout to reduce clutter (but always logs to the aformentioned
  Datasets-specific log file).
  
  After initialization, always use the `get_logger()` method to correctly
  set whether to log to stdout. Example usage:
  ```
  logger = DatasetLogger(__name__)
  logger.get_logger().info("This logs to file and stdout")
  logger.get_logger(log_to_stdout=False).info("This logs to file only)
  logger.get_logger().warning("Can call the usual Logger methods")
  ```
docstr: Internal method to initialize the logger and the extra file handler
  for writing to the Dataset log file. Not intended (nor necessary)
  to call explicitly. Assumes that `ray.init()` has already been called prior
  to calling this method; otherwise raises a `ValueError`.
docstr_tok: ["Internal","method","to","initialize","the","logger","and","the","extra","file","handler","for","writing","to","the","Dataset","log","file",".","Not","intended","(","nor","necessary",")","to","call","explicitly",".","Assumes","that","`","ray.init","(",")","`","has","already","been","called","prior","to","calling","this","method",";","otherwise","raises","a","`","ValueError","`","."]
code: def _initialize_logger(self) -> logging.Logger:
      """Internal method to initialize the logger and the extra file handler
      for writing to the Dataset log file. Not intended (nor necessary)
      to call explicitly. Assumes that `ray.init()` has already been called prior
      to calling this method; otherwise raises a `ValueError`."""
  
      # We initialize a logger using the given base `log_name`, which
      # logs to stdout. Logging with this logger to stdout is enabled by the
      # `log_to_stdout` parameter in `self.get_logger()`.
      stdout_logger = logging.getLogger(self.log_name)
      stdout_logger.setLevel(LOGGER_LEVEL.upper())
  
      # The second logger that we initialize is designated as the main logger,
      # which has the above `stdout_logger` as an ancestor.
      # This is so that even if the file handler is not initialized below,
      # the logger will still propagate up to `stdout_logger` for the option
      # of logging to stdout.
      logger = logging.getLogger(f"{self.log_name}.logfile")
      # We need to set the log level again when explicitly
      # initializing a new logger (otherwise can have undesirable level).
      logger.setLevel(LOGGER_LEVEL.upper())
  
      # If ray.init() is called and the global node session directory path
      # is valid, we can create the additional handler to write to the
      # Dataset log file. If this is not the case (e.g. when used in Ray
      # Client), then we skip initializing the FileHandler.
      global_node = ray._private.worker._global_node
      if global_node is not None:
          # Add a FileHandler to write to the specific Ray Datasets log file
          # at `DatasetLogger.DEFAULT_DATASET_LOG_PATH`, using the standard
          # default logger format used by the root logger
          session_dir = global_node.get_session_dir_path()
          datasets_log_path = os.path.join(
              session_dir,
              DatasetLogger.DEFAULT_DATASET_LOG_PATH,
          )
          file_log_formatter = logging.Formatter(fmt=LOGGER_FORMAT)
          file_log_handler = logging.FileHandler(datasets_log_path)
          file_log_handler.setLevel(LOGGER_LEVEL.upper())
          file_log_handler.setFormatter(file_log_formatter)
          logger.addHandler(file_log_handler)
      return logger
  
file_path: ray/python/ray/data/_internal/dataset_logger.py
imports: import logging
  import os
  import ray
  from ray._private.ray_constants import LOGGER_FORMAT, LOGGER_LEVEL
label_desc: Use image node_id 2 for calling the DatasetLogger obj's underlying member method code with example usage: obj._initialize_logger() and returns: logger