/**
   * Log finish time of task.
   *
   * @param taskId task id
   * @param taskType MAP or REDUCE
   * @param finishTime finish timeof task in ms
   */
  public void logTaskFinished(TaskID taskId, String taskType, long finishTime, Counters counters) {

    if (disableHistory) {
      return;
    }

    JobID id = taskId.getJobID();
    if (!this.jobId.equals(id)) {
      throw new RuntimeException("JobId from task: " + id + " does not match expected: " + jobId);
    }

    if (null != writers) {
      log(
          writers,
          RecordTypes.Task,
          new Keys[] {
            Keys.TASKID, Keys.TASK_TYPE,
            Keys.TASK_STATUS, Keys.FINISH_TIME,
            Keys.COUNTERS
          },
          new String[] {
            taskId.toString(),
            taskType,
            Values.SUCCESS.name(),
            String.valueOf(finishTime),
            counters.makeEscapedCompactString()
          });
    }
  }
  /**
   * Log job finished. closes the job file in history.
   *
   * @param finishTime finish time of job in ms.
   * @param finishedMaps no of maps successfully finished.
   * @param finishedReduces no of reduces finished sucessfully.
   * @param failedMaps no of failed map tasks. (includes killed)
   * @param failedReduces no of failed reduce tasks. (includes killed)
   * @param killedMaps no of killed map tasks.
   * @param killedReduces no of killed reduce tasks.
   * @param counters the counters from the job
   */
  public void logFinished(
      long finishTime,
      int finishedMaps,
      int finishedReduces,
      int failedMaps,
      int failedReduces,
      int killedMaps,
      int killedReduces,
      Counters mapCounters,
      Counters reduceCounters,
      Counters counters) {
    if (disableHistory) {
      return;
    }

    if (null != writers) {
      log(
          writers,
          RecordTypes.Job,
          new Keys[] {
            Keys.JOBID,
            Keys.FINISH_TIME,
            Keys.JOB_STATUS,
            Keys.FINISHED_MAPS,
            Keys.FINISHED_REDUCES,
            Keys.FAILED_MAPS,
            Keys.FAILED_REDUCES,
            Keys.KILLED_MAPS,
            Keys.KILLED_REDUCES,
            Keys.MAP_COUNTERS,
            Keys.REDUCE_COUNTERS,
            Keys.COUNTERS
          },
          new String[] {
            jobId.toString(),
            Long.toString(finishTime),
            Values.SUCCESS.name(),
            String.valueOf(finishedMaps),
            String.valueOf(finishedReduces),
            String.valueOf(failedMaps),
            String.valueOf(failedReduces),
            String.valueOf(killedMaps),
            String.valueOf(killedReduces),
            mapCounters.makeEscapedCompactString(),
            reduceCounters.makeEscapedCompactString(),
            counters.makeEscapedCompactString()
          },
          true);

      closeAndClear(writers);
    }

    // NOTE: history cleaning stuff deleted from here. We should do that
    // somewhere else!
  }
  /**
   * Log finished event of this task.
   *
   * @param taskAttemptId task attempt id
   * @param shuffleFinished shuffle finish time
   * @param sortFinished sort finish time
   * @param finishTime finish time of task
   * @param hostName host name where task attempt executed
   * @param taskType Whether the attempt is cleanup or setup or reduce
   * @param stateString the state string of the attempt
   * @param counter counters of the attempt
   */
  public void logReduceTaskFinished(
      TaskAttemptID taskAttemptId,
      long shuffleFinished,
      long sortFinished,
      long finishTime,
      String hostName,
      String taskType,
      String stateString,
      Counters counter) {
    if (disableHistory) {
      return;
    }

    JobID id = taskAttemptId.getJobID();
    if (!this.jobId.equals(id)) {
      throw new RuntimeException("JobId from task: " + id + " does not match expected: " + jobId);
    }

    if (null != writers) {
      log(
          writers,
          RecordTypes.ReduceAttempt,
          new Keys[] {
            Keys.TASK_TYPE, Keys.TASKID,
            Keys.TASK_ATTEMPT_ID, Keys.TASK_STATUS,
            Keys.SHUFFLE_FINISHED, Keys.SORT_FINISHED,
            Keys.FINISH_TIME, Keys.HOSTNAME,
            Keys.STATE_STRING, Keys.COUNTERS
          },
          new String[] {
            taskType,
            taskAttemptId.getTaskID().toString(),
            taskAttemptId.toString(),
            Values.SUCCESS.name(),
            String.valueOf(shuffleFinished),
            String.valueOf(sortFinished),
            String.valueOf(finishTime),
            hostName,
            stateString,
            counter.makeEscapedCompactString()
          });
    }
  }