container/src/main/java/com/streamsets/datacollector/execution/alerts/MetricRuleEvaluatorHelper.java
private static long getTimeFromRunner(
    MetricRegistry metrics,
    String runnerMetricName
  ) {
    // First get number of total runners from the runtime gauge
    RuntimeStats runtimeStats = (RuntimeStats) ((Gauge)getMetric(metrics, "RuntimeStatsGauge.gauge", MetricType.GAUGE)).getValue();
    long totalRunners = runtimeStats.getTotalRunners();

    long currentTime = System.currentTimeMillis();
    long maxTime = 0;

    // Then iterate over all runners and find the biggest time difference
    for(int runnerId = 0; runnerId < totalRunners; runnerId++) {
      Map<String, Object> runnerMetrics = (Map<String, Object>) ((Gauge)getMetric(metrics, "runner." + runnerId, MetricType.GAUGE)).getValue();

      // Get current value
      long value = (long) runnerMetrics.getOrDefault(runnerMetricName, 0L);

      // Zero means that the runner is not in use at all and thus calculating running time makes no sense
      if(value == 0) {
        continue;
      }

      long runTime = currentTime - value;
      if(maxTime < runTime) {
        maxTime = runTime;
      }
    }

    return maxTime;
  }
private static long getTimeFromRunner(
    MetricRegistry metrics,
    String runnerMetricName
  ) {
    // First get number of total runners from the runtime gauge
    RuntimeStats runtimeStats = (RuntimeStats) ((Gauge)getMetric(metrics, "RuntimeStatsGauge.gauge", MetricType.GAUGE)).getValue();
    long totalRunners = runtimeStats.getTotalRunners();

    long currentTime = System.currentTimeMillis();
    long maxTime = 0;

    // Then iterate over all runners and find the biggest time difference
    for(int runnerId = 0; runnerId < totalRunners; runnerId++) {
      Map<String, Object> runnerMetrics = (Map<String, Object>) ((Gauge)getMetric(metrics, "runner." + runnerId, MetricType.GAUGE)).getValue();

      // Get current value
      long value = (long) runnerMetrics.getOrDefault(runnerMetricName, 0L);

      // Zero means that the runner is not in use at all and thus calculating running time makes no sense
      if(value == 0) {
        continue;
      }

      long runTime = currentTime - value;
      if(maxTime < runTime) {
        maxTime = runTime;
      }
    }

    return maxTime;
  }
Return calculated metric - from all the runners that are available for given pipeline, return the biggest difference
between given metric and System.currentTimeMillis(). The semantic is that the runner metric stores start time of
certain events (batch start time, stage start time) and we need to find out what is the longer running time for one
of those metrics.

@param metrics Metric registry for given pipeline.
@param runnerMetricName Name of the PipeRunner metric that contains start time of given action.
@return