class_docstr: Datmo Logging singleton
  
  Good info https://fangpenlin.com/posts/2012/08/26/good-logging-practice-in-python/
docstr: Returns a python logger with logging level set
  
  Parameters
  ----------
  name : string
      Name of the logger.  eg datmo.core.snapshot or __name__
  file_name : string
      Log file name. default = log.txt
  
  Returns
  -------
  logging.Logger
      Python logger
docstr_tok: ["Returns","a","python","logger","with","logging","level","set","Parameters","--","--","--","--","--","name",":","string","Name","of","the","logger",".","eg","datmo.core.snapshot","or","__name__","file_name",":","string","Log","file","name",".","default","=","log.txt","Returns","--","--","--","-","logging.Logger","Python","logger"]
code: def get_logger(name=__name__, file_name="log.txt"):
      """Returns a python logger with logging level set
  
      Parameters
      ----------
      name : string
          Name of the logger.  eg datmo.core.snapshot or __name__
      file_name : string
          Log file name. default = log.txt
  
      Returns
      -------
      logging.Logger
          Python logger
      """
  
      # get or create logging path
      if DatmoLogger().logging_path == None:
          DatmoLogger().logging_path = tempfile.mkdtemp()
  
      logging_path = DatmoLogger().logging_path
      logfile_path = os.path.join(logging_path, file_name)
  
      if not os.path.exists(logging_path):
          os.makedirs(logging_path)
  
      # cache the logger and return it otherwise handlers will get added multiple times
      # and result in multiple messages to the same file
      logger_hash = hashlib.sha1(
          (name + file_name).encode("utf-8")
      ).hexdigest()
  
      if logger_hash in DatmoLogger().loggers:
          # if file still exists then use cached logger
          # if file has been deleted manually, then empty cached obj
          # and allow re-initialization
          if os.path.exists(logfile_path):
              return DatmoLogger().loggers[logger_hash]
          else:
              DatmoLogger().loggers[logger_hash] = None
  
      # create logger based on name
      log = logging.getLogger(logger_hash)
      log.setLevel(DatmoLogger().logging_level)
  
      # cache logger
      DatmoLogger().loggers[logger_hash] = log
  
      # console logging
      # log_stdout = logging.StreamHandler("ext://sys.stdout")
      # log_stdout.setLevel(logging.DEBUG)
      # log.addHandler(log_stdout)
  
      if hasattr(logging, "handlers"):
          log_file_handler = logging.handlers.RotatingFileHandler(
              logfile_path, mode="a", maxBytes=10485760, backupCount=10
          )
          log_file_handler.setLevel(DatmoLogger().logging_level)
          log_file_handler.setFormatter(
              logging.Formatter(
                  "%(asctime)s - ["
                  + name
                  + "@%(module)s.%(funcName)s] [%(levelname)s] - %(message)s"
              )
          )
          log.addHandler(log_file_handler)
      else:
          print("warning logging doesnt have handlers")
  
      return log
  
file_path: datmo/datmo/core/util/logger.py
imports: import hashlib
  import logging
  import logging.handlers
  import os
  import tempfile
  import time
  from datmo.core.util.misc_functions import grep
label_desc: Use image node_id 6 for calling the DatmoLogger obj's underlying member method code with example usage: obj.get_logger(name, file_name) and returns: log, DatmoLogger