001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018/* 019 * Copyright 2016 Josh Elser 020 * 021 * Licensed under the Apache License, Version 2.0 (the "License"); 022 * you may not use this file except in compliance with the License. 023 * You may obtain a copy of the License at 024 * 025 * http://www.apache.org/licenses/LICENSE-2.0 026 * 027 * Unless required by applicable law or agreed to in writing, software 028 * distributed under the License is distributed on an "AS IS" BASIS, 029 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 030 * See the License for the specific language governing permissions and 031 * limitations under the License. 032 */ 033package org.apache.hadoop.hbase.metrics.impl; 034 035import java.util.Map; 036import org.apache.commons.lang3.StringUtils; 037import org.apache.hadoop.hbase.metrics.Counter; 038import org.apache.hadoop.hbase.metrics.Gauge; 039import org.apache.hadoop.hbase.metrics.Histogram; 040import org.apache.hadoop.hbase.metrics.Meter; 041import org.apache.hadoop.hbase.metrics.Metric; 042import org.apache.hadoop.hbase.metrics.MetricRegistry; 043import org.apache.hadoop.hbase.metrics.MetricRegistryInfo; 044import org.apache.hadoop.hbase.metrics.Timer; 045import org.apache.hadoop.metrics2.MetricsCollector; 046import org.apache.hadoop.metrics2.MetricsInfo; 047import org.apache.hadoop.metrics2.MetricsRecordBuilder; 048import org.apache.hadoop.metrics2.lib.Interns; 049import org.apache.hadoop.metrics2.lib.MutableHistogram; 050import org.apache.yetus.audience.InterfaceAudience; 051import org.slf4j.Logger; 052import org.slf4j.LoggerFactory; 053 054/** 055 * This is the adapter from "HBase Metrics Framework", implemented in hbase-metrics-api and 056 * hbase-metrics modules to the Hadoop Metrics2 framework. This adapter is not a metric source, 057 * but a helper to be able to collect all of the Metric's in the MetricRegistry using the 058 * MetricsCollector and MetricsRecordBuilder. 059 * 060 * Some of the code is forked from https://github.com/joshelser/dropwizard-hadoop-metrics2. 061 */ 062@InterfaceAudience.Private 063public class HBaseMetrics2HadoopMetricsAdapter { 064 private static final Logger LOG 065 = LoggerFactory.getLogger(HBaseMetrics2HadoopMetricsAdapter.class); 066 private static final String EMPTY_STRING = ""; 067 068 public HBaseMetrics2HadoopMetricsAdapter() { 069 } 070 071 /** 072 * Iterates over the MetricRegistry and adds them to the {@code collector}. 073 * 074 * @param collector A metrics collector 075 */ 076 public void snapshotAllMetrics(MetricRegistry metricRegistry, 077 MetricsCollector collector) { 078 MetricRegistryInfo info = metricRegistry.getMetricRegistryInfo(); 079 MetricsRecordBuilder builder = collector.addRecord(Interns.info(info.getMetricsName(), 080 info.getMetricsDescription())); 081 builder.setContext(info.getMetricsContext()); 082 083 snapshotAllMetrics(metricRegistry, builder); 084 } 085 086 /** 087 * Iterates over the MetricRegistry and adds them to the {@code builder}. 088 * 089 * @param builder A record builder 090 */ 091 public void snapshotAllMetrics(MetricRegistry metricRegistry, MetricsRecordBuilder builder) { 092 Map<String, Metric> metrics = metricRegistry.getMetrics(); 093 094 for (Map.Entry<String, Metric> e: metrics.entrySet()) { 095 // Always capitalize the name 096 String name = StringUtils.capitalize(e.getKey()); 097 Metric metric = e.getValue(); 098 099 if (metric instanceof Gauge) { 100 addGauge(name, (Gauge<?>) metric, builder); 101 } else if (metric instanceof Counter) { 102 addCounter(name, (Counter)metric, builder); 103 } else if (metric instanceof Histogram) { 104 addHistogram(name, (Histogram)metric, builder); 105 } else if (metric instanceof Meter) { 106 addMeter(name, (Meter)metric, builder); 107 } else if (metric instanceof Timer) { 108 addTimer(name, (Timer)metric, builder); 109 } else { 110 LOG.info("Ignoring unknown Metric class " + metric.getClass().getName()); 111 } 112 } 113 } 114 115 private void addGauge(String name, Gauge<?> gauge, MetricsRecordBuilder builder) { 116 final MetricsInfo info = Interns.info(name, EMPTY_STRING); 117 final Object o = gauge.getValue(); 118 119 // Figure out which gauge types metrics2 supports and call the right method 120 if (o instanceof Integer) { 121 builder.addGauge(info, (int) o); 122 } else if (o instanceof Long) { 123 builder.addGauge(info, (long) o); 124 } else if (o instanceof Float) { 125 builder.addGauge(info, (float) o); 126 } else if (o instanceof Double) { 127 builder.addGauge(info, (double) o); 128 } else { 129 LOG.warn("Ignoring Gauge (" + name + ") with unhandled type: " + o.getClass()); 130 } 131 } 132 133 private void addCounter(String name, Counter counter, MetricsRecordBuilder builder) { 134 MetricsInfo info = Interns.info(name, EMPTY_STRING); 135 builder.addCounter(info, counter.getCount()); 136 } 137 138 /** 139 * Add Histogram value-distribution data to a Hadoop-Metrics2 record building. 140 * 141 * @param name A base name for this record. 142 * @param histogram A histogram to measure distribution of values. 143 * @param builder A Hadoop-Metrics2 record builder. 144 */ 145 private void addHistogram(String name, Histogram histogram, MetricsRecordBuilder builder) { 146 MutableHistogram.snapshot(name, EMPTY_STRING, histogram, builder, true); 147 } 148 149 /** 150 * Add Dropwizard-Metrics rate information to a Hadoop-Metrics2 record builder, converting the 151 * rates to the appropriate unit. 152 * 153 * @param builder A Hadoop-Metrics2 record builder. 154 * @param name A base name for this record. 155 */ 156 private void addMeter(String name, Meter meter, MetricsRecordBuilder builder) { 157 builder.addGauge(Interns.info(name + "_count", EMPTY_STRING), meter.getCount()); 158 builder.addGauge(Interns.info(name + "_mean_rate", EMPTY_STRING), meter.getMeanRate()); 159 builder.addGauge(Interns.info(name + "_1min_rate", EMPTY_STRING), meter.getOneMinuteRate()); 160 builder.addGauge(Interns.info(name + "_5min_rate", EMPTY_STRING), meter.getFiveMinuteRate()); 161 builder.addGauge(Interns.info(name + "_15min_rate", EMPTY_STRING), 162 meter.getFifteenMinuteRate()); 163 } 164 165 private void addTimer(String name, Timer timer, MetricsRecordBuilder builder) { 166 addMeter(name, timer.getMeter(), builder); 167 addHistogram(name, timer.getHistogram(), builder); 168 } 169}