View Javadoc

1   /**
2    * Copyright 2010 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package org.apache.hadoop.hbase.ipc;
22  
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  import org.apache.hadoop.metrics.MetricsContext;
26  import org.apache.hadoop.metrics.MetricsRecord;
27  import org.apache.hadoop.metrics.MetricsUtil;
28  import org.apache.hadoop.metrics.Updater;
29  import org.apache.hadoop.metrics.util.MetricsRegistry;
30  import org.apache.hadoop.metrics.util.MetricsTimeVaryingRate;
31  
32  import java.lang.reflect.Method;
33  
34  /**
35   *
36   * This class is for maintaining  the various RPC statistics
37   * and publishing them through the metrics interfaces.
38   * This also registers the JMX MBean for RPC.
39   * <p>
40   * This class has a number of metrics variables that are publicly accessible;
41   * these variables (objects) have methods to update their values;
42   * for example:
43   *  <p> {@link #rpcQueueTime}.inc(time)
44   *
45   */
46  public class HBaseRpcMetrics implements Updater {
47    private MetricsRecord metricsRecord;
48    private static Log LOG = LogFactory.getLog(HBaseRpcMetrics.class);
49    private final HBaseRPCStatistics rpcStatistics;
50  
51    public HBaseRpcMetrics(String hostName, String port) {
52      MetricsContext context = MetricsUtil.getContext("rpc");
53      metricsRecord = MetricsUtil.createRecord(context, "metrics");
54  
55      metricsRecord.setTag("port", port);
56  
57      LOG.info("Initializing RPC Metrics with hostName="
58          + hostName + ", port=" + port);
59  
60      context.registerUpdater(this);
61  
62      initMethods(HMasterInterface.class);
63      initMethods(HMasterRegionInterface.class);
64      initMethods(HRegionInterface.class);
65      rpcStatistics = new HBaseRPCStatistics(this.registry, hostName, port);
66    }
67  
68  
69    /**
70     * The metrics variables are public:
71     *  - they can be set directly by calling their set/inc methods
72     *  -they can also be read directly - e.g. JMX does this.
73     */
74    public final MetricsRegistry registry = new MetricsRegistry();
75  
76    public MetricsTimeVaryingRate rpcQueueTime = new MetricsTimeVaryingRate("RpcQueueTime", registry);
77    public MetricsTimeVaryingRate rpcProcessingTime = new MetricsTimeVaryingRate("RpcProcessingTime", registry);
78  
79    //public Map <String, MetricsTimeVaryingRate> metricsList = Collections.synchronizedMap(new HashMap<String, MetricsTimeVaryingRate>());
80  
81    private void initMethods(Class<? extends HBaseRPCProtocolVersion> protocol) {
82      for (Method m : protocol.getDeclaredMethods()) {
83        if (get(m.getName()) == null)
84          create(m.getName());
85      }
86    }
87  
88    private MetricsTimeVaryingRate get(String key) {
89      return (MetricsTimeVaryingRate) registry.get(key);
90    }
91    private MetricsTimeVaryingRate create(String key) {
92      return new MetricsTimeVaryingRate(key, this.registry);
93    }
94  
95    public void inc(String name, int amt) {
96      MetricsTimeVaryingRate m = get(name);
97      if (m == null) {
98        LOG.warn("Got inc() request for method that doesnt exist: " +
99        name);
100       return; // ignore methods that dont exist.
101     }
102     m.inc(amt);
103   }
104 
105   public void createMetrics(Class<?> []ifaces) {
106     for (Class<?> iface : ifaces) {
107       Method[] methods = iface.getMethods();
108       for (Method method : methods) {
109         if (get(method.getName()) == null)
110           create(method.getName());
111       }
112     }
113   }
114 
115   /**
116    * Push the metrics to the monitoring subsystem on doUpdate() call.
117    * @param context ctx
118    */
119   public void doUpdates(MetricsContext context) {
120     rpcQueueTime.pushMetric(metricsRecord);
121     rpcProcessingTime.pushMetric(metricsRecord);
122 
123     synchronized (registry) {
124       // Iterate through the registry to propagate the different rpc metrics.
125 
126       for (String metricName : registry.getKeyList() ) {
127         MetricsTimeVaryingRate value = (MetricsTimeVaryingRate) registry.get(metricName);
128 
129         value.pushMetric(metricsRecord);
130       }
131     }
132     metricsRecord.update();
133   }
134 
135   public void shutdown() {
136     if (rpcStatistics != null)
137       rpcStatistics.shutdown();
138   }
139 }