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__,))