def log(
        message: typing.Union[str, typing.List[str]],
        whitespace: int = 0,
        whitespace_top: int = 0,
        whitespace_bottom: int = 0,
        indent_by: int = 0,
        trace: bool = True,
        file_path: str = None,
        append_to_file: bool = True,
        **kwargs
) -> str:
    """
    Logs a message to the console with the formatting support beyond a simple
    print statement or logger statement.

    :param message:
        The primary log message for the entry
    :param whitespace:
        The number of lines of whitespace to append to the beginning and end
        of the log message when printed to the console
    :param whitespace_top:
        The number of lines of whitespace to append to the beginning only of
        the log message when printed to the console. If whitespace_top and
        whitespace are both specified, the larger of the two values will be
        used.
    :param whitespace_bottom:
        The number of lines of whitespace to append to the end of the log
        message when printed to the console. If whitespace_bottom and
        whitespace are both specified, the larger of hte two values will be
        used.
    :param indent_by:
        The number of spaces that each line of text should be indented
    :param trace:
        Whether or not to trace the output to the console
    :param file_path:
        A path to a logging file where the output should be written
    :param append_to_file:
        Whether or not the log entry should be overwritten or appended to the
        log file specified in the file_path argument
    :param kwargs:
    """
    m = add_to_message(message)
    for key, value in kwargs.items():
        m.append('{key}: {value}'.format(key=key, value=value))

    pre_whitespace = int(max(whitespace, whitespace_top))
    post_whitespace = int(max(whitespace, whitespace_bottom))

    if pre_whitespace:
        m.insert(0, max(0, pre_whitespace - 1) * '\n')
    if post_whitespace:
        m.append(max(0, post_whitespace - 1) * '\n')

    message = indent('\n'.join(m), ' ' * indent_by)
    raw(
        message=message,
        trace=trace,
        file_path=file_path,
        append_to_file=append_to_file
    )
    return message