public void initAfterRegister() {
    // Make sure we capture the same metrics as Hadoop2 metrics system, via annotations.
    if (allMetrics != null) return;
    allMetrics = new HashMap<>();
    for (Field field : this.getClass().getDeclaredFields()) {
      for (Annotation annotation : field.getAnnotations()) {
        if (!(annotation instanceof Metric)) continue;
        try {
          field.setAccessible(true);
          allMetrics.put(field.getName(), (MutableMetric) field.get(this));
        } catch (IllegalAccessException ex) {
          break; // Not expected, access by the same class.
        }
        break;
      }
    }

    // Set up codahale if enabled; we cannot tag the values so just prefix them for the JMX view.
    Metrics chMetrics = MetricsFactory.getInstance();
    if (!(chMetrics instanceof CodahaleMetrics)) return;

    List<String> codahaleNames = new ArrayList<>();
    for (Map.Entry<String, MutableMetric> e : allMetrics.entrySet()) {
      MutableMetric metric = e.getValue();
      MetricsVariable<?> var = null;
      if (metric instanceof MutableCounterInt) {
        var = new CodahaleCounterWrapper((MutableCounterInt) metric);
      } else if (metric instanceof MutableGaugeInt) {
        var = new CodahaleGaugeWrapper((MutableGaugeInt) metric);
      }
      if (var == null) continue; // Unexpected metric type.
      String name = "WM_" + poolName + "_" + e.getKey();
      codahaleNames.add(name);
      chMetrics.addGauge(name, var);
    }
    this.codahaleGaugeNames = codahaleNames;
  }
A wrapper for metrics for single WM pool. This outputs metrics both to Codahale and standard
Hadoop metrics, in parallel. The codahale output is prefixed with pool name and is mostly
for the JMX view, or to look at when Hadoop metrics are not set up. Hadoop metrics are output
because they can be tagged properly rather than prefixed, so they are better for dashboards.
ql/src/java/org/apache/hadoop/hive/ql/exec/tez/WmPoolMetrics.java