blob: 9ab884ece3e591384e4d805982f3fcaad9c85bd2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.metrics2.lib;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.metrics2.MetricsException;
import org.apache.hadoop.metrics2.MetricsInfo;
import org.apache.hadoop.metrics2.annotation.Metric;
import org.apache.hadoop.metrics2.annotation.Metrics;
@InterfaceAudience.Private
@InterfaceStability.Evolving
public class MutableMetricsFactory {
private static final Log LOG = LogFactory.getLog(MutableMetricsFactory.class);
MutableMetric newForField(Field field, Metric annotation,
MetricsRegistry registry) {
if (LOG.isDebugEnabled()) {
LOG.debug("field "+ field +" with annotation "+ annotation);
}
MetricsInfo info = getInfo(annotation, field);
MutableMetric metric = newForField(field, annotation);
if (metric != null) {
registry.add(info.name(), metric);
return metric;
}
final Class<?> cls = field.getType();
if (cls == MutableCounterInt.class) {
return registry.newCounter(info, 0);
}
if (cls == MutableCounterLong.class) {
return registry.newCounter(info, 0L);
}
if (cls == MutableGaugeInt.class) {
return registry.newGauge(info, 0);
}
if (cls == MutableGaugeLong.class) {
return registry.newGauge(info, 0L);
}
if (cls == MutableRate.class) {
return registry.newRate(info.name(), info.description(),
annotation.always());
}
if (cls == MutableRates.class) {
return new MutableRates(registry);
}
if (cls == MutableStat.class) {
return registry.newStat(info.name(), info.description(),
annotation.sampleName(), annotation.valueName(),
annotation.always());
}
throw new MetricsException("Unsupported metric field "+ field.getName() +
" of type "+ field.getType().getName());
}
MutableMetric newForMethod(Object source, Method method, Metric annotation,
MetricsRegistry registry) {
if (LOG.isDebugEnabled()) {
LOG.debug("method "+ method +" with annotation "+ annotation);
}
MetricsInfo info = getInfo(annotation, method);
MutableMetric metric = newForMethod(source, method, annotation);
metric = metric != null ? metric :
new MethodMetric(source, method, info, annotation.type());
registry.add(info.name(), metric);
return metric;
}
/**
* Override to handle custom mutable metrics for fields
* @param field of the metric
* @param annotation of the field
* @return a new metric object or null
*/
protected MutableMetric newForField(Field field, Metric annotation) {
return null;
}
/**
* Override to handle custom mutable metrics for methods
* @param source the metrics source object
* @param method to return the metric
* @param annotation of the method
* @return a new metric object or null
*/
protected MutableMetric newForMethod(Object source, Method method,
Metric annotation) {
return null;
}
protected MetricsInfo getInfo(Metric annotation, Field field) {
return getInfo(annotation, getName(field));
}
protected String getName(Field field) {
return StringUtils.capitalize(field.getName());
}
protected MetricsInfo getInfo(Metric annotation, Method method) {
return getInfo(annotation, getName(method));
}
protected MetricsInfo getInfo(Class<?> cls, Metrics annotation) {
String name = annotation.name();
String about = annotation.about();
String name2 = name.isEmpty() ? cls.getSimpleName() : name;
return Interns.info(name2, about.isEmpty() ? name2 : about);
}
protected String getName(Method method) {
String methodName = method.getName();
if (methodName.startsWith("get")) {
return StringUtils.capitalize(methodName.substring(3));
}
return StringUtils.capitalize(methodName);
}
protected MetricsInfo getInfo(Metric annotation, String defaultName) {
String[] value = annotation.value();
if (value.length == 2) {
return Interns.info(value[0], value[1]);
}
if (value.length == 1) {
return Interns.info(defaultName, value[0]);
}
return Interns.info(defaultName, defaultName);
}
}