| /* |
| * 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); |
| } |
| } |