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  package org.apache.hadoop.hbase.master.metrics;
19  
20  import java.io.IOException;
21  
22  import org.apache.commons.logging.Log;
23  import org.apache.commons.logging.LogFactory;
24  import org.apache.hadoop.hbase.metrics.HBaseInfo;
25  import org.apache.hadoop.hbase.metrics.MetricsRate;
26  import org.apache.hadoop.hbase.metrics.PersistentMetricsTimeVaryingRate;
27  import org.apache.hadoop.metrics.ContextFactory;
28  import org.apache.hadoop.metrics.MetricsContext;
29  import org.apache.hadoop.metrics.MetricsRecord;
30  import org.apache.hadoop.metrics.MetricsUtil;
31  import org.apache.hadoop.metrics.Updater;
32  import org.apache.hadoop.metrics.jvm.JvmMetrics;
33  import org.apache.hadoop.metrics.util.MetricsLongValue;
34  import org.apache.hadoop.metrics.util.MetricsRegistry;
35  
36  
37  /**
38   * This class is for maintaining the various master statistics
39   * and publishing them through the metrics interfaces.
40   * <p>
41   * This class has a number of metrics variables that are publicly accessible;
42   * these variables (objects) have methods to update their values.
43   */
44  public class MasterMetrics implements Updater {
45    private final Log LOG = LogFactory.getLog(this.getClass());
46    private final MetricsRecord metricsRecord;
47    private final MetricsRegistry registry = new MetricsRegistry();
48    private final MasterStatistics masterStatistics;
49  
50    private long lastUpdate = System.currentTimeMillis();
51    private long lastExtUpdate = System.currentTimeMillis();
52    private long extendedPeriod = 0;
53  /*
54     * Count of requests to the cluster since last call to metrics update
55     */
56    private final MetricsRate cluster_requests =
57      new MetricsRate("cluster_requests", registry);
58  
59    /** Time it takes to finish HLog.splitLog() */
60    final PersistentMetricsTimeVaryingRate splitTime =
61      new PersistentMetricsTimeVaryingRate("splitTime", registry);
62  
63    /** Size of HLog files being split */
64    final PersistentMetricsTimeVaryingRate splitSize =
65      new PersistentMetricsTimeVaryingRate("splitSize", registry);
66  
67    public MasterMetrics(final String name) {
68      MetricsContext context = MetricsUtil.getContext("hbase");
69      metricsRecord = MetricsUtil.createRecord(context, "master");
70      metricsRecord.setTag("Master", name);
71      context.registerUpdater(this);
72      JvmMetrics.init("Master", name);
73      HBaseInfo.init();
74  
75      // expose the MBean for metrics
76      masterStatistics = new MasterStatistics(this.registry);
77  
78      // get custom attributes
79      try {
80        Object m = 
81          ContextFactory.getFactory().getAttribute("hbase.extendedperiod");
82        if (m instanceof String) {
83          this.extendedPeriod = Long.parseLong((String) m)*1000;
84        }
85      } catch (IOException ioe) {
86        LOG.info("Couldn't load ContextFactory for Metrics config info");
87      }
88  
89      LOG.info("Initialized");
90    }
91  
92    public void shutdown() {
93      if (masterStatistics != null)
94        masterStatistics.shutdown();
95    }
96  
97    /**
98     * Since this object is a registered updater, this method will be called
99     * periodically, e.g. every 5 seconds.
100    * @param unused
101    */
102   public void doUpdates(MetricsContext unused) {
103     synchronized (this) {
104       this.lastUpdate = System.currentTimeMillis();
105 
106       // has the extended period for long-living stats elapsed?
107       if (this.extendedPeriod > 0 &&
108           this.lastUpdate - this.lastExtUpdate >= this.extendedPeriod) {
109         this.lastExtUpdate = this.lastUpdate;
110         this.splitTime.resetMinMaxAvg();
111         this.splitSize.resetMinMaxAvg();
112         this.resetAllMinMax();
113       }
114 
115       this.cluster_requests.pushMetric(metricsRecord);
116       this.splitTime.pushMetric(metricsRecord);
117       this.splitSize.pushMetric(metricsRecord);
118     }
119     this.metricsRecord.update();
120   }
121 
122   public void resetAllMinMax() {
123     // Nothing to do
124   }
125   
126   /**
127    * Record a single instance of a split
128    * @param time time that the split took
129    * @param size length of original HLogs that were split
130    */
131   public synchronized void addSplit(long time, long size) {
132     splitTime.inc(time);
133     splitSize.inc(size);
134   }
135 
136   /**
137    * @return Count of requests.
138    */
139   public float getRequests() {
140     return this.cluster_requests.getPreviousIntervalValue();
141   }
142 
143   /**
144    * @param inc How much to add to requests.
145    */
146   public void incrementRequests(final int inc) {
147     this.cluster_requests.inc(inc);
148   }
149 }