public synchronized void flush() {
   try {
     int last = KettleLogStore.getLastBufferLineNr();
     StringBuffer buffer =
         KettleLogStore.getAppender().getBuffer(logChannelId, false, lastBufferLineNr, last);
     logFileOutputStream.write(buffer.toString().getBytes());
     lastBufferLineNr = last;
     logFileOutputStream.flush();
   } catch (Exception e) {
     exception = new KettleException("There was an error logging to file '" + logFile + "'", e);
   }
 }
  protected String getLogBuffer(
      VariableSpace space, String logChannelId, LogStatus status, String limit) {

    StringBuffer buffer = KettleLogStore.getAppender().getBuffer(logChannelId, true);

    if (Const.isEmpty(limit)) {
      String defaultLimit = space.getVariable(Const.KETTLE_LOG_SIZE_LIMIT, null);
      if (!Const.isEmpty(defaultLimit)) {
        limit = defaultLimit;
      }
    }

    // See if we need to limit the amount of rows
    //
    int nrLines = Const.isEmpty(limit) ? -1 : Const.toInt(space.environmentSubstitute(limit), -1);

    if (nrLines > 0) {
      int start = buffer.length() - 1;
      for (int i = 0; i < nrLines && start > 0; i++) {
        start = buffer.lastIndexOf(Const.CR, start - 1);
      }
      if (start > 0) {
        buffer.delete(0, start + Const.CR.length());
      }
    }

    return buffer.append(Const.CR + status.getStatus().toUpperCase() + Const.CR).toString();
  }
  /**
   * Create a new log channel file writer
   *
   * @param logChannelId The log channel (+children) to write to the log file
   * @param logFile The logging file to write to
   * @param appending set to true if you want to append to an existing file
   * @param pollingInterval The polling interval in milliseconds.
   * @throws KettleException in case the specified log file can't be created.
   */
  public LogChannelFileWriter(
      String logChannelId, FileObject logFile, boolean appending, int pollingInterval)
      throws KettleException {
    this.logChannelId = logChannelId;
    this.logFile = logFile;
    this.appending = appending;
    this.pollingInterval = pollingInterval;

    active = new AtomicBoolean(false);
    lastBufferLineNr = KettleLogStore.getLastBufferLineNr();

    try {
      logFileOutputStream = KettleVFS.getOutputStream(logFile, appending);
    } catch (IOException e) {
      throw new KettleException(
          "There was an error while trying to open file '" + logFile + "' for writing", e);
    }
  }