@Override
  public void log(Level logLevel, String message) {
    if (!messageConsumers.containsKey(logLevel)) {
      return;
    }
    Consumer<String> messageConsumer = messageConsumers.get(logLevel);

    singleThreadedExecutor.execute(
        () -> {
          boolean didErase = eraseFooter();
          // If a previous footer was erased, the message needs to go up a line.
          if (didErase) {
            if (enableTwoCursorUpJump) {
              messageConsumer.accept(String.format(CURSOR_UP_SEQUENCE_TEMPLATE, 2));
              messageConsumer.accept(message);
            } else {
              messageConsumer.accept(CURSOR_UP_SEQUENCE + message);
            }
          } else {
            messageConsumer.accept(message);
          }

          printInBold(footerLines);
        });
  }
Creates a new {@link AnsiLoggerWithFooter}.

@param messageConsumers map from each {@link Level} to a corresponding message logger
@param singleThreadedExecutor a {@link SingleThreadedExecutor} to ensure that all messages are
    logged in a sequential, deterministic order
@param enableTwoCursorUpJump allows the logger to move the cursor up twice at once. Fixes a
    logging issue in Maven (https://github.com/GoogleContainerTools/jib/issues/1952) but causes
    a problem in Gradle (https://github.com/GoogleContainerTools/jib/issues/1963)
jib-plugins-common/src/main/java/com/google/cloud/tools/jib/plugins/common/logging/AnsiLoggerWithFooter.java