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, but 057 * a helper to be able to collect all of the Metric's in the MetricRegistry using the 058 * MetricsCollector and MetricsRecordBuilder. Some of the code is forked from 059 * https://github.com/joshelser/dropwizard-hadoop-metrics2. 060 */ 061@InterfaceAudience.Private 062public class HBaseMetrics2HadoopMetricsAdapter { 063 private static final Logger LOG = 064 LoggerFactory.getLogger(HBaseMetrics2HadoopMetricsAdapter.class); 065 private static final String EMPTY_STRING = ""; 066 067 public HBaseMetrics2HadoopMetricsAdapter() { 068 } 069 070 /** 071 * Iterates over the MetricRegistry and adds them to the {@code collector}. 072 * @param collector A metrics collector 073 */ 074 public void snapshotAllMetrics(MetricRegistry metricRegistry, MetricsCollector collector) { 075 MetricRegistryInfo info = metricRegistry.getMetricRegistryInfo(); 076 MetricsRecordBuilder builder = 077 collector.addRecord(Interns.info(info.getMetricsName(), info.getMetricsDescription())); 078 builder.setContext(info.getMetricsContext()); 079 080 snapshotAllMetrics(metricRegistry, builder); 081 } 082 083 /** 084 * Iterates over the MetricRegistry and adds them to the {@code builder}. 085 * @param builder A record builder 086 */ 087 public void snapshotAllMetrics(MetricRegistry metricRegistry, MetricsRecordBuilder builder) { 088 Map<String, Metric> metrics = metricRegistry.getMetrics(); 089 090 for (Map.Entry<String, Metric> e : metrics.entrySet()) { 091 // Always capitalize the name 092 String name = StringUtils.capitalize(e.getKey()); 093 Metric metric = e.getValue(); 094 095 if (metric instanceof Gauge) { 096 addGauge(name, (Gauge<?>) metric, builder); 097 } else if (metric instanceof Counter) { 098 addCounter(name, (Counter) metric, builder); 099 } else if (metric instanceof Histogram) { 100 addHistogram(name, (Histogram) metric, builder); 101 } else if (metric instanceof Meter) { 102 addMeter(name, (Meter) metric, builder); 103 } else if (metric instanceof Timer) { 104 addTimer(name, (Timer) metric, builder); 105 } else { 106 LOG.info("Ignoring unknown Metric class " + metric.getClass().getName()); 107 } 108 } 109 } 110 111 private void addGauge(String name, Gauge<?> gauge, MetricsRecordBuilder builder) { 112 final MetricsInfo info = Interns.info(name, EMPTY_STRING); 113 final Object o = gauge.getValue(); 114 115 // Figure out which gauge types metrics2 supports and call the right method 116 if (o instanceof Integer) { 117 builder.addGauge(info, (int) o); 118 } else if (o instanceof Long) { 119 builder.addGauge(info, (long) o); 120 } else if (o instanceof Float) { 121 builder.addGauge(info, (float) o); 122 } else if (o instanceof Double) { 123 builder.addGauge(info, (double) o); 124 } else { 125 LOG.warn("Ignoring Gauge (" + name + ") with unhandled type: " + o.getClass()); 126 } 127 } 128 129 private void addCounter(String name, Counter counter, MetricsRecordBuilder builder) { 130 MetricsInfo info = Interns.info(name, EMPTY_STRING); 131 builder.addCounter(info, counter.getCount()); 132 } 133 134 /** 135 * Add Histogram value-distribution data to a Hadoop-Metrics2 record building. 136 * @param name A base name for this record. 137 * @param histogram A histogram to measure distribution of values. 138 * @param builder A Hadoop-Metrics2 record builder. 139 */ 140 private void addHistogram(String name, Histogram histogram, MetricsRecordBuilder builder) { 141 MutableHistogram.snapshot(name, EMPTY_STRING, histogram, builder, true); 142 } 143 144 /** 145 * Add Dropwizard-Metrics rate information to a Hadoop-Metrics2 record builder, converting the 146 * rates to the appropriate unit. 147 * @param builder A Hadoop-Metrics2 record builder. 148 * @param name A base name for this record. 149 */ 150 private void addMeter(String name, Meter meter, MetricsRecordBuilder builder) { 151 builder.addGauge(Interns.info(name + "_count", EMPTY_STRING), meter.getCount()); 152 builder.addGauge(Interns.info(name + "_mean_rate", EMPTY_STRING), meter.getMeanRate()); 153 builder.addGauge(Interns.info(name + "_1min_rate", EMPTY_STRING), meter.getOneMinuteRate()); 154 builder.addGauge(Interns.info(name + "_5min_rate", EMPTY_STRING), meter.getFiveMinuteRate()); 155 builder.addGauge(Interns.info(name + "_15min_rate", EMPTY_STRING), 156 meter.getFifteenMinuteRate()); 157 } 158 159 private void addTimer(String name, Timer timer, MetricsRecordBuilder builder) { 160 addMeter(name, timer.getMeter(), builder); 161 addHistogram(name, timer.getHistogram(), builder); 162 } 163}