def _configure_logger(fmt, quiet, level, fpath,
    pre_hooks, post_hooks, metric_grouping_interval):
    level = getattr(logging, level.upper())
    global _GLOBAL_LOG_CONFIGURED
    if _GLOBAL_LOG_CONFIGURED:
        return
    def wrap_hook(fn):
        @wraps(fn)
        def processor(logger, method_name, event_dict):
            fn(event_dict)
            return event_dict
        return processor
    processors = define_log_processors()
    processors.extend(
        [ wrap_hook(h) for h in pre_hooks ]
    )
    if metric_grouping_interval:
        processors.append(metrics_grouping_processor)
    log_renderer = define_log_renderer(fmt, fpath, quiet)
    stderr_required = (not quiet)
    pretty_to_stderr = (
        stderr_required
        and (
            fmt == "pretty"
            or (fmt is None and sys.stderr.isatty())
        )
    )
    should_inject_pretty_renderer = (
        pretty_to_stderr
        and not isinstance(log_renderer, structlog.dev.ConsoleRenderer)
    )
    if should_inject_pretty_renderer:
        stderr_required = False
        processors.append(StderrConsoleRenderer())
    processors.append(log_renderer)
    processors.extend(
        [ wrap_hook(h) for h in post_hooks ]
    )
    streams = []
    if stderr_required:
        streams.append(sys.stderr)
    if fpath is not None:
        streams.append(open(fpath, 'a'))
    assert len(streams) != 0, "cannot configure logger for 0 streams"
    stream = streams[0] if len(streams) == 1 else Stream(*streams)
    atexit.register(stream.close)
    structlog.configure(
        processors=processors,
        context_class=dict,
        logger_factory=LevelLoggerFactory(stream, level=level),
        wrapper_class=BoundLevelLogger,
        cache_logger_on_first_use=True,
    )
    stdlib_root_log = logging.getLogger()
    stdlib_root_log.addHandler(StdlibStructlogHandler())
    stdlib_root_log.setLevel(level)
    _GLOBAL_LOG_CONFIGURED = True