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.metrics;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22 import org.apache.hadoop.classification.InterfaceAudience;
23 import org.apache.hadoop.metrics.MetricsRecord;
24 import org.apache.hadoop.metrics.util.MetricsRegistry;
25 import org.apache.hadoop.metrics.util.MetricsTimeVaryingRate;
26 import org.apache.hadoop.util.StringUtils;
27
28 /**
29 * This class extends MetricsTimeVaryingRate to let the metrics
30 * persist past a pushMetric() call
31 */
32 @Deprecated
33 @InterfaceAudience.Private
34 public class PersistentMetricsTimeVaryingRate extends MetricsTimeVaryingRate {
35 protected static final Log LOG =
36 LogFactory.getLog("org.apache.hadoop.hbase.metrics");
37
38 protected boolean reset = false;
39 protected long lastOper = 0;
40 protected long totalOps = 0;
41
42 /**
43 * Constructor - create a new metric
44 * @param nam the name of the metrics to be used to publish the metric
45 * @param registry - where the metrics object will be registered
46 * @param description metrics description
47 */
48 public PersistentMetricsTimeVaryingRate(final String nam,
49 final MetricsRegistry registry,
50 final String description) {
51 super(nam, registry, description);
52 }
53
54 /**
55 * Constructor - create a new metric
56 * @param nam the name of the metrics to be used to publish the metric
57 * @param registry - where the metrics object will be registered
58 */
59 public PersistentMetricsTimeVaryingRate(final String nam,
60 MetricsRegistry registry) {
61 this(nam, registry, NO_DESCRIPTION);
62 }
63
64 /**
65 * Push updated metrics to the mr.
66 *
67 * Note this does NOT push to JMX
68 * (JMX gets the info via {@link #getPreviousIntervalAverageTime()} and
69 * {@link #getPreviousIntervalNumOps()}
70 *
71 * @param mr owner of this metric
72 */
73 @Override
74 public synchronized void pushMetric(final MetricsRecord mr) {
75 // this will reset the currentInterval & num_ops += prevInterval()
76 super.pushMetric(mr);
77 // since we're retaining prevInterval(), we don't want to do the incr
78 // instead, we want to set that value because we have absolute ops
79 try {
80 mr.setMetric(getName() + "_num_ops", totalOps);
81 } catch (Exception e) {
82 LOG.info("pushMetric failed for " + getName() + "\n" +
83 StringUtils.stringifyException(e));
84 }
85 if (reset) {
86 // use the previous avg as our starting min/max/avg
87 super.inc(getPreviousIntervalAverageTime());
88 reset = false;
89 } else {
90 // maintain the stats that pushMetric() cleared
91 maintainStats();
92 }
93 }
94
95 /**
96 * Increment the metrics for numOps operations
97 * @param numOps - number of operations
98 * @param time - time for numOps operations
99 */
100 @Override
101 public synchronized void inc(final int numOps, final long time) {
102 super.inc(numOps, time);
103 totalOps += numOps;
104 }
105
106 /**
107 * Increment the metrics for numOps operations
108 * @param time - time for numOps operations
109 */
110 @Override
111 public synchronized void inc(final long time) {
112 super.inc(time);
113 ++totalOps;
114 }
115
116 /**
117 * Rollover to a new interval
118 * NOTE: does not reset numOps. this is an absolute value
119 */
120 public synchronized void resetMinMaxAvg() {
121 reset = true;
122 }
123
124 /* MetricsTimeVaryingRate will reset every time pushMetric() is called
125 * This is annoying for long-running stats that might not get a single
126 * operation in the polling period. This function ensures that values
127 * for those stat entries don't get reset.
128 */
129 protected void maintainStats() {
130 int curOps = this.getPreviousIntervalNumOps();
131 if (curOps > 0) {
132 long curTime = this.getPreviousIntervalAverageTime();
133 long totalTime = curTime * curOps;
134 if (curTime == 0 || totalTime / curTime == curOps) {
135 super.inc(curOps, totalTime);
136 } else {
137 LOG.info("Stats for " + this.getName() + " overflowed! resetting");
138 }
139 }
140 }
141 }