View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.hbase.client.metrics;
20  
21  import java.io.DataInput;
22  import java.io.DataOutput;
23  import java.io.IOException;
24  import java.util.ArrayList;
25  import java.util.Collection;
26  
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  import org.apache.hadoop.hbase.HConstants;
30  import org.apache.hadoop.io.Writable;
31  import org.apache.hadoop.metrics.util.MetricsBase;
32  import org.apache.hadoop.metrics.util.MetricsRegistry;
33  import org.apache.hadoop.metrics.util.MetricsTimeVaryingLong;
34  
35  
36  /**
37   * Provides client-side metrics related to scan operations
38   * The data can be passed to mapreduce framework or other systems.
39   * Currently metrics framework won't be able to support the scenario
40   * where multiple scan instances run on the same machine trying to
41   * update the same metric. We use metrics objects in the class,
42   * so that it can be easily switched to metrics framework later when it support
43   * this scenario.
44   * Some of these metrics are general for any client operation such as put
45   * However, there is no need for this. So they are defined under scan operation
46   * for now.
47   */
48  public class ScanMetrics implements Writable {
49  
50    private static final byte SCANMETRICS_VERSION = (byte)1;
51    private static final Log LOG = LogFactory.getLog(ScanMetrics.class);
52    private MetricsRegistry registry = new MetricsRegistry();
53  
54    /**
55     * number of RPC calls
56     */
57    public final MetricsTimeVaryingLong countOfRPCcalls =
58      new MetricsTimeVaryingLong("RPC_CALLS", registry);
59  
60    /**
61     * number of remote RPC calls
62     */
63    public final MetricsTimeVaryingLong countOfRemoteRPCcalls =
64      new MetricsTimeVaryingLong("REMOTE_RPC_CALLS", registry);
65  
66    /**
67     * sum of milliseconds between sequential next calls
68     */
69    public final MetricsTimeVaryingLong sumOfMillisSecBetweenNexts =
70      new MetricsTimeVaryingLong("MILLIS_BETWEEN_NEXTS", registry);
71  
72    /**
73     * number of NotServingRegionException caught
74     */
75    public final MetricsTimeVaryingLong countOfNSRE =
76      new MetricsTimeVaryingLong("NOT_SERVING_REGION_EXCEPTION", registry);
77  
78    /**
79     * number of bytes in Result objects from region servers
80     */
81    public final MetricsTimeVaryingLong countOfBytesInResults =
82      new MetricsTimeVaryingLong("BYTES_IN_RESULTS", registry);
83  
84    /**
85     * number of bytes in Result objects from remote region servers
86     */
87    public final MetricsTimeVaryingLong countOfBytesInRemoteResults =
88      new MetricsTimeVaryingLong("BYTES_IN_REMOTE_RESULTS", registry);
89  
90    /**
91     * number of regions
92     */
93    public final MetricsTimeVaryingLong countOfRegions =
94      new MetricsTimeVaryingLong("REGIONS_SCANNED", registry);
95  
96    /**
97     * number of RPC retries
98     */
99    public final MetricsTimeVaryingLong countOfRPCRetries =
100     new MetricsTimeVaryingLong("RPC_RETRIES", registry);
101 
102   /**
103    * number of remote RPC retries
104    */
105   public final MetricsTimeVaryingLong countOfRemoteRPCRetries =
106     new MetricsTimeVaryingLong("REMOTE_RPC_RETRIES", registry);
107 
108   /**
109    * constructor
110    */
111   public ScanMetrics () {
112   }
113 
114   /**
115    * serialize all the MetricsTimeVaryingLong
116    */
117   public void write(DataOutput out) throws IOException {
118     out.writeByte(SCANMETRICS_VERSION);
119     Collection<MetricsBase> mbs = registry.getMetricsList();
120 
121     // we only handle MetricsTimeVaryingLong for now.
122     int metricsCount = 0;
123     for (MetricsBase mb : mbs) {
124       if ( mb instanceof MetricsTimeVaryingLong) {
125         metricsCount++;
126       } else {
127         throw new IOException("unsupported metrics type. metrics name: "
128           + mb.getName() + ", metrics description: " + mb.getDescription());
129       }
130     }
131 
132     out.writeInt(metricsCount);
133     for (MetricsBase mb : mbs) {
134       out.writeUTF(mb.getName());
135       out.writeLong(((MetricsTimeVaryingLong) mb).getCurrentIntervalValue());
136     }
137   }
138 
139   public void readFields(DataInput in) throws IOException {
140     int version = in.readByte();
141     if (version > (int)SCANMETRICS_VERSION) {
142       throw new IOException("version " + version + " not supported");
143     }
144 
145     int metricsCount = in.readInt();
146     for (int i=0; i<metricsCount; i++) {
147       String metricsName = in.readUTF();
148       long v = in.readLong();
149       MetricsBase mb = registry.get(metricsName);
150       if ( mb instanceof MetricsTimeVaryingLong) {
151         ((MetricsTimeVaryingLong) mb).inc(v);
152       } else {
153         LOG.warn("unsupported metrics type. metrics name: "
154           + mb.getName() + ", metrics description: " + mb.getDescription());
155       }
156     }
157   }
158 
159   public MetricsTimeVaryingLong[] getMetricsTimeVaryingLongArray() {
160     Collection<MetricsBase> mbs = registry.getMetricsList();
161     ArrayList<MetricsTimeVaryingLong> mlv =
162       new ArrayList<MetricsTimeVaryingLong>();
163     for (MetricsBase mb : mbs) {
164       if ( mb instanceof MetricsTimeVaryingLong) {
165         mlv.add((MetricsTimeVaryingLong) mb);
166       }
167     }
168     return mlv.toArray(new MetricsTimeVaryingLong[mlv.size()]);
169   }
170 
171 }