code: @Override
    public void onJobCompletion(JobContext jobContext)
        throws Exception {
      super.onJobCompletion(jobContext);
      long startTime = jobContext.getJobState().getPropAsLong(JOB_START_TIME);
      jobLauncherMetrics.totalJobsCompleted.incrementAndGet();
      Instrumented.updateTimer(Optional.of(jobLauncherMetrics.timeForCompletedJobs), System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
      if (jobContext.getJobState().getState() == JobState.RunningState.FAILED) {
        jobLauncherMetrics.totalJobsFailed.incrementAndGet();
        Instrumented.updateTimer(Optional.of(jobLauncherMetrics.timeForFailedJobs), System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
      } else {
        jobLauncherMetrics.totalJobsCommitted.incrementAndGet();
        Instrumented.updateTimer(Optional.of(jobLauncherMetrics.timeForCommittedJobs), System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
      }
    }
docs: From {@link org.apache.gobblin.runtime.AbstractJobLauncher#launchJob(JobListener)}, the final
  job state should only be FAILED or COMMITTED. This means the completed jobs metrics covers
  both failed jobs and committed jobs.