View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  /*
19   * Copyright 2016 Josh Elser
20   *
21   * Licensed under the Apache License, Version 2.0 (the "License");
22   * you may not use this file except in compliance with the License.
23   * You may obtain a copy of the License at
24   *
25   *     http://www.apache.org/licenses/LICENSE-2.0
26   *
27   * Unless required by applicable law or agreed to in writing, software
28   * distributed under the License is distributed on an "AS IS" BASIS,
29   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
30   * See the License for the specific language governing permissions and
31   * limitations under the License.
32   */
33  package org.apache.hadoop.hbase.metrics.impl;
34  
35  import java.util.Map;
36  
37  import org.apache.commons.lang.StringUtils;
38  import org.apache.commons.logging.Log;
39  import org.apache.commons.logging.LogFactory;
40  import org.apache.hadoop.hbase.metrics.Counter;
41  import org.apache.hadoop.hbase.metrics.Gauge;
42  import org.apache.hadoop.hbase.metrics.Histogram;
43  import org.apache.hadoop.hbase.metrics.Meter;
44  import org.apache.hadoop.hbase.metrics.Metric;
45  import org.apache.hadoop.hbase.metrics.MetricRegistry;
46  import org.apache.hadoop.hbase.metrics.MetricRegistryInfo;
47  import org.apache.hadoop.hbase.metrics.Timer;
48  import org.apache.hadoop.metrics2.MetricsCollector;
49  import org.apache.hadoop.metrics2.MetricsInfo;
50  import org.apache.hadoop.metrics2.MetricsRecordBuilder;
51  import org.apache.hadoop.metrics2.lib.Interns;
52  import org.apache.hadoop.metrics2.lib.MutableHistogram;
53  
54  /**
55   * This is the adapter from "HBase Metrics Framework", implemented in hbase-metrics-api and
56   * hbase-metrics modules to the Hadoop Metrics2 framework. This adapter is not a metric source,
57   * but a helper to be able to collect all of the Metric's in the MetricRegistry using the
58   * MetricsCollector and MetricsRecordBuilder.
59   *
60   * Some of the code is forked from https://github.com/joshelser/dropwizard-hadoop-metrics2.
61   */
62  public class HBaseMetrics2HadoopMetricsAdapter {
63    private static final Log LOG
64        = LogFactory.getLog(HBaseMetrics2HadoopMetricsAdapter.class);
65    private static final String EMPTY_STRING = "";
66  
67    public HBaseMetrics2HadoopMetricsAdapter() {
68    }
69  
70    /**
71     * Iterates over the MetricRegistry and adds them to the {@code collector}.
72     *
73     * @param collector A metrics collector
74     */
75    public void snapshotAllMetrics(MetricRegistry metricRegistry,
76                                   MetricsCollector collector) {
77      MetricRegistryInfo info = metricRegistry.getMetricRegistryInfo();
78      MetricsRecordBuilder builder = collector.addRecord(Interns.info(info.getMetricsName(),
79          info.getMetricsDescription()));
80      builder.setContext(info.getMetricsContext());
81  
82      snapshotAllMetrics(metricRegistry, builder);
83    }
84  
85    /**
86     * Iterates over the MetricRegistry and adds them to the {@code builder}.
87     *
88     * @param builder A record builder
89     */
90    public void snapshotAllMetrics(MetricRegistry metricRegistry, MetricsRecordBuilder builder) {
91      Map<String, Metric> metrics = metricRegistry.getMetrics();
92  
93      for (Map.Entry<String, Metric> e: metrics.entrySet()) {
94        // Always capitalize the name
95        String name = StringUtils.capitalize(e.getKey());
96        Metric metric = e.getValue();
97  
98        if (metric instanceof Gauge) {
99          addGauge(name, (Gauge<?>) metric, builder);
100       } else if (metric instanceof Counter) {
101         addCounter(name, (Counter)metric, builder);
102       } else if (metric instanceof Histogram) {
103         addHistogram(name, (Histogram)metric, builder);
104       } else if (metric instanceof Meter) {
105         addMeter(name, (Meter)metric, builder);
106       } else if (metric instanceof Timer) {
107         addTimer(name, (Timer)metric, builder);
108       } else {
109         LOG.info("Ignoring unknown Metric class " + metric.getClass().getName());
110       }
111     }
112   }
113 
114   private void addGauge(String name, Gauge<?> gauge, MetricsRecordBuilder builder) {
115     final MetricsInfo info = Interns.info(name, EMPTY_STRING);
116     final Object o = gauge.getValue();
117 
118     // Figure out which gauge types metrics2 supports and call the right method
119     if (o instanceof Integer) {
120       builder.addGauge(info, (int) o);
121     } else if (o instanceof Long) {
122       builder.addGauge(info, (long) o);
123     } else if (o instanceof Float) {
124       builder.addGauge(info, (float) o);
125     } else if (o instanceof Double) {
126       builder.addGauge(info, (double) o);
127     } else {
128       LOG.warn("Ignoring Gauge (" + name + ") with unhandled type: " + o.getClass());
129     }
130   }
131 
132   private void addCounter(String name, Counter counter, MetricsRecordBuilder builder) {
133     MetricsInfo info = Interns.info(name, EMPTY_STRING);
134     builder.addCounter(info, counter.getCount());
135   }
136 
137   /**
138    * Add Histogram value-distribution data to a Hadoop-Metrics2 record building.
139    *
140    * @param name A base name for this record.
141    * @param histogram A histogram to measure distribution of values.
142    * @param builder A Hadoop-Metrics2 record builder.
143    */
144   private void addHistogram(String name, Histogram histogram, MetricsRecordBuilder builder) {
145     MutableHistogram.snapshot(name, EMPTY_STRING, histogram, builder, true);
146   }
147 
148   /**
149    * Add Dropwizard-Metrics rate information to a Hadoop-Metrics2 record builder, converting the
150    * rates to the appropriate unit.
151    *
152    * @param builder A Hadoop-Metrics2 record builder.
153    * @param name A base name for this record.
154    */
155   private void addMeter(String name, Meter meter, MetricsRecordBuilder builder) {
156     builder.addGauge(Interns.info(name + "_count", EMPTY_STRING), meter.getCount());
157     builder.addGauge(Interns.info(name + "_mean_rate", EMPTY_STRING), meter.getMeanRate());
158     builder.addGauge(Interns.info(name + "_1min_rate", EMPTY_STRING), meter.getOneMinuteRate());
159     builder.addGauge(Interns.info(name + "_5min_rate", EMPTY_STRING), meter.getFiveMinuteRate());
160     builder.addGauge(Interns.info(name + "_15min_rate", EMPTY_STRING),
161         meter.getFifteenMinuteRate());
162   }
163 
164   private void addTimer(String name, Timer timer, MetricsRecordBuilder builder) {
165     addMeter(name, timer.getMeter(), builder);
166     addHistogram(name, timer.getHistogram(), builder);
167   }
168 }