Configure root logger to log INFO to stderr and DEBUG to log file.

    The log file is appended to. Stderr uses a terse format, while the log file
    uses a verbose unambiguous format.

    Root level is set to INFO.

    Parameters
    ----------
    log_file : ~pathlib.Path
        File to log to.

    Returns
    -------
    ~typing.Tuple[~logging.StreamHandler, ~logging.FileHandler]
        Stderr and file handler respectively.

def configure(log_file):
    '''
    Configure root logger to log INFO to stderr and DEBUG to log file.

    The log file is appended to. Stderr uses a terse format, while the log file
    uses a verbose unambiguous format.

    Root level is set to INFO.

    Parameters
    ----------
    log_file : ~pathlib.Path
        File to log to.

    Returns
    -------
    ~typing.Tuple[~logging.StreamHandler, ~logging.FileHandler]
        Stderr and file handler respectively.
    '''
    # Note: do not use logging.basicConfig as it does not play along with caplog in testing
    root_logger = logging.getLogger()
    root_logger.setLevel(logging.INFO)

    # log info to stderr in terse format
    stderr_handler = logging.StreamHandler() # to stderr
    stderr_handler.setLevel(logging.INFO)
    stderr_handler.setFormatter(logging.Formatter('{levelname[0]}: {message}', style='{'))
    root_logger.addHandler(stderr_handler)

    # log debug to file in full format
    file_handler = logging.FileHandler(str(log_file))
    file_handler.setLevel(logging.DEBUG)
    file_handler.setFormatter(logging.Formatter('{levelname[0]} {asctime} {name} ({module}:{lineno}):\n{message}\n', style='{'))
    root_logger.addHandler(file_handler)

    return stderr_handler, file_handler