Retrieve a logger given its name and initialize it by passing it
    appropriate arguments from the configuration.  (Unnecessary
    arguments will be logged, and missing required arguments will
    cause a TypeError to be thrown.)  The result should be a callable.

    :param name: The name of the handler to look up.
    :param logname: The name of the log section.
    :param args: A dictionary of arguments for the handler.

    :returns: A callable taking a single argument: the message to be
              logged.

def get_handler(name, logname, args):
    """
    Retrieve a logger given its name and initialize it by passing it
    appropriate arguments from the configuration.  (Unnecessary
    arguments will be logged, and missing required arguments will
    cause a TypeError to be thrown.)  The result should be a callable.

    :param name: The name of the handler to look up.
    :param logname: The name of the log section.
    :param args: A dictionary of arguments for the handler.

    :returns: A callable taking a single argument: the message to be
              logged.
    """

    factory = _lookup_handler(name)

    # What arguments are we passing to the handler?
    available = set(args.keys())

    # Now, let's introspect the factory to pass it the right arguments
    if inspect.isclass(factory):
        argspec = inspect.getargspec(factory.__init__)
        ismethod = True
    else:
        argspec = inspect.getargspec(factory)
        ismethod = inspect.ismethod(factory)

    # Now, let's select the arguments we'll be passing in from the
    # args dictionary
    argnames = argspec.args[2 + ismethod:]
    recognized = set(argnames)

    # Now, which ones are required?
    if argspec.defaults:
        required = set(argnames[:len(argnames) - len(argspec.defaults)])
    else:
        required = set(argnames)
    missing = required - available
    if missing:
        raise TypeError("Missing required parameters: %s" %
                        ', '.join(repr(arg) for arg in sorted(missing)))

    # OK, let's determine the argument types
    type_map = getattr(factory, '_bark_types', {})

    # Now go convert the arguments
    kwargs = {}
    additional = set()
    for arg, value in args.items():
        # Should we ignore it?
        if not argspec.keywords and arg not in recognized:
            additional.add(arg)
            continue

        # Translate the value, first
        target_type = type_map.get(arg, lambda x: x)
        if target_type is bool:
            target_type = boolean
        try:
            value = target_type(value)
        except ValueError as exc:
            raise ValueError("Argument %r: invalid %s value %r: %s" %
                             (arg, target_type.__name__, value, exc))

        # OK, save it
        kwargs[arg] = value

    # Log any unused arguments
    if additional:
        LOG.warn("Unused arguments for handler of type %r for log %r: %s" %
                 (name, logname, ', '.join(repr(arg)
                                           for arg in sorted(additional))))

    # OK, we have now constructed the arguments to feed to the handler
    # factory; call it and return the result
    return factory(name, logname, **kwargs)