code: def start_logging(log_fpath=None, mode='a', appname='default', log_dir=None):
      r
      global __UTOOL_ROOT_LOGGER__
      global __UTOOL_PRINT__
      global __UTOOL_WRITE__
      global __UTOOL_FLUSH__
      global __CURRENT_LOG_FPATH__
      if LOGGING_VERBOSE:
          print('[utool] start_logging()')
      if __UTOOL_ROOT_LOGGER__ is None and __IN_MAIN_PROCESS__ and not __inside_doctest():
          if LOGGING_VERBOSE:
              print('[utool] start_logging()... rootcheck OK')
          if log_fpath is None:
              log_fpath = get_log_fpath(num='next', appname=appname, log_dir=log_dir)
          __CURRENT_LOG_FPATH__ = log_fpath
          if VERBOSE or LOGGING_VERBOSE:
              startmsg = ('logging to log_fpath=%r' % log_fpath)
              _utool_print()(startmsg)
          __UTOOL_ROOT_LOGGER__ = logging.getLogger('root')
          __UTOOL_ROOT_LOGGER__.setLevel('DEBUG')
          logfile_handler = logging.FileHandler(log_fpath, mode=mode)
          stdout_handler = CustomStreamHandler(__UTOOL_STDOUT__)
          stdout_handler.terminator = ''
          add_logging_handler(logfile_handler, format_='file')
          add_logging_handler(stdout_handler, format_='stdout')
          __UTOOL_ROOT_LOGGER__.propagate = False
          __UTOOL_ROOT_LOGGER__.setLevel(logging.DEBUG)
          def utool_flush(*args):
              stdout_handler.flush()
          def utool_write(*args):
              msg = ', '.join(map(six.text_type, args))
              __UTOOL_ROOT_LOGGER__.info(msg)
          if not PRINT_ALL_CALLERS:
              def utool_print(*args):
                  endline = '\n'
                  try:
                      msg = ', '.join(map(six.text_type, args))
                      return  __UTOOL_ROOT_LOGGER__.info(msg + endline)
                  except UnicodeDecodeError:
                      new_msg = ', '.join(map(meta_util_six.ensure_unicode, args))
                      return  __UTOOL_ROOT_LOGGER__.info(new_msg + endline)
          else:
              def utool_print(*args):
                  import utool as ut
                  utool_flush()
                  endline = '\n'
                  __UTOOL_ROOT_LOGGER__.info('\n\n----------')
                  __UTOOL_ROOT_LOGGER__.info(ut.get_caller_name(range(0, 20)))
                  return  __UTOOL_ROOT_LOGGER__.info(', '.join(map(six.text_type, args)) + endline)
          def utool_printdbg(*args):
              return  __UTOOL_ROOT_LOGGER__.debug(', '.join(map(six.text_type, args)))
          __UTOOL_WRITE__    = utool_write
          __UTOOL_FLUSH__    = utool_flush
          __UTOOL_PRINT__    = utool_print
          if VERBOSE or LOGGING_VERBOSE:
              __UTOOL_PRINT__('<__LOG_START__>')
              __UTOOL_PRINT__(startmsg)
      else:
          if LOGGING_VERBOSE:
              print('[utool] start_logging()... FAILED TO START')
              print('DEBUG INFO')
              print('__inside_doctest() = %r' % (__inside_doctest(),))
              print('__IN_MAIN_PROCESS__ = %r' % (__IN_MAIN_PROCESS__,))
              print('__UTOOL_ROOT_LOGGER__ = %r' % (__UTOOL_ROOT_LOGGER__,))