code: public void addSlf4jLogMessageConsumer(BiConsumer<String, Slf4jLogMessageContext> slf4jLogMessageConsumer) {
          checkNotNull(slf4jLogMessageConsumer, "slf4jLogMessageConsumer parameter is NULL!");
          addLogMessageConsumer(logMessage -> {
              slf4jLogMessageConsumer.accept(logMessage, parseSlf4jContextFromLogMessage(logMessage));
          });
      }
docs: When a complete log message is available (from server output data) that
  message is parsed for its slf4j context (logger name, logger level etc.)
  and the specified {@code BiConsumer} is invoked with the log message and
  slf4j context.
  
  <p>Use this method only if you want a behavior that differentiates from the
  default behavior as enabled by method
  {@link #enableDefaultSlf4jLoggingOfOutputData()}.
  
  <p>NOTE: You might want to call method {@link #clearOutPutStreams()} before
  calling this method.
  
  <p>implementation detail:
  <ul>
  <li>if log message begins with {@code [debug]} then log level is set to
  {@code DEBUG}, otherwise log level is {@code INFO}.</li>
  <li>the appium sub module name is parsed from the log message and used as
  logger name (prefixed with "appium.service.", all lower case, spaces
  removed). If no appium sub module is detected then "appium.service" is
  used as logger name.</li>
  </ul>
  Example log-message: "[ADB] Cannot read version codes of " is logged by
  {@code appium.service.adb} at level {@code INFO} <br>
  Example log-message: "[debug] [XCUITest] Xcode version set to 'x.y.z' "
  is logged by {@code appium.service.xcuitest} at level {@code DEBUG}
  <br>
  
  @param slf4jLogMessageConsumer
  BiConsumer block to be executed when a log message is
  available.