code: def log(message, level=None, name=None, filename=None):
      
  
      if level is None:
          level = settings.log_level
      if name is None:
          name = settings.log_name
      if filename is None:
          filename = settings.log_filename
  
      # if logging to file is turned on
      if settings.log_file:
          # get the current logger (or create a new one, if none), then log
          # message at requested level
          logger = get_logger(level=level, name=name, filename=filename)
          if level == lg.DEBUG:
              logger.debug(message)
          elif level == lg.INFO:
              logger.info(message)
          elif level == lg.WARNING:
              logger.warning(message)
          elif level == lg.ERROR:
              logger.error(message)
  
      # if logging to console is turned on, convert message to ascii and print to
      # the console
      if settings.log_console:
          # capture current stdout, then switch it to the console, print the
          # message, then switch back to what had been the stdout. this prevents
          # logging to notebook - instead, it goes to console
          standard_out = sys.stdout
          sys.stdout = sys.__stdout__
  
          # convert message to ascii for console display so it doesn't break
          # windows terminals
          message = unicodedata.normalize('NFKD', make_str(message)).encode('ascii', errors='replace').decode()
          print(message)
          sys.stdout = standard_out
docs: Write a message to the log file and/or print to the the console.
  
      Parameters
      ----------
      message : string
          the content of the message to log
      level : int
          one of the logger.level constants
      name : string
          name of the logger
      filename : string
          name of the log file
  
      Returns
      -------
      None