public void println( LogMessageInterface logMessage, LogLevel channelLogLevel ) {

    String subject = logMessage.getSubject();

    if ( !logMessage.getLevel().isVisible( channelLogLevel ) ) {
      return; // not for our eyes.
    }

    if ( subject == null ) {
      subject = DEFAULT_LOG_SUBJECT;
    }

    // Are the message filtered?
    // apply filter if defined, and not Error level
    boolean applyFilter = !logMessage.getLevel().isError() && !Utils.isEmpty( filter );
    if ( applyFilter && !subject.contains( filter ) && !logMessage.toString().contains( filter ) ) {
      return; // "filter" not found in row: don't show!
    }

    callBeforeLog();

    KettleLoggingEvent loggingEvent = new KettleLoggingEvent( logMessage, System.currentTimeMillis(),
      logMessage.getLevel() );
    KettleLogStore.getAppender().addLogggingEvent( loggingEvent );

    if ( this.fileWriter == null ) {
      this.fileWriter = LoggingRegistry.getInstance().getLogChannelFileWriterBuffer( logChannelId );
    }

    // add to buffer
    if ( this.fileWriter != null ) {
      this.fileWriter.addEvent( loggingEvent );
    }

    callAfterLog();
  }
@Test
  public void testPrintlnWithNullLogChannelFileWriterBuffer() {
    LoggingBuffer loggingBuffer = mock( LoggingBuffer.class );
    kettleLogStoreMockedStatic.when( KettleLogStore::getAppender ).thenReturn( loggingBuffer );

    logChannel.println( logMsgInterface, LogLevel.BASIC );
    verify( logChFileWriterBuffer, times( 1 ) ).addEvent( any( KettleLoggingEvent.class ) );
    verify( loggingBuffer, times( 1 ) ).addLogggingEvent( any( KettleLoggingEvent.class ) );
  }