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.regionserver;
20  
21  import java.util.concurrent.atomic.AtomicBoolean;
22  
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  import org.apache.hadoop.hbase.classification.InterfaceAudience;
26  import org.apache.hadoop.metrics2.MetricHistogram;
27  import org.apache.hadoop.metrics2.MetricsRecordBuilder;
28  import org.apache.hadoop.metrics2.lib.DynamicMetricsRegistry;
29  
30  @InterfaceAudience.Private
31  public class MetricsUserSourceImpl implements MetricsUserSource {
32    private static final Log LOG = LogFactory.getLog(MetricsUserSourceImpl.class);
33  
34    private final String userNamePrefix;
35  
36    private final String user;
37  
38    private final String userGetKey;
39    private final String userScanTimeKey;
40    private final String userPutKey;
41    private final String userDeleteKey;
42    private final String userIncrementKey;
43    private final String userAppendKey;
44    private final String userReplayKey;
45  
46    private MetricHistogram getHisto;
47    private MetricHistogram scanTimeHisto;
48    private MetricHistogram putHisto;
49    private MetricHistogram deleteHisto;
50    private MetricHistogram incrementHisto;
51    private MetricHistogram appendHisto;
52    private MetricHistogram replayHisto;
53  
54    private final int hashCode;
55  
56    private AtomicBoolean closed = new AtomicBoolean(false);
57    private final MetricsUserAggregateSourceImpl agg;
58    private final DynamicMetricsRegistry registry;
59  
60    public MetricsUserSourceImpl(String user, MetricsUserAggregateSourceImpl agg) {
61      if (LOG.isDebugEnabled()) {
62        LOG.debug("Creating new MetricsUserSourceImpl for user " + user);
63      }
64  
65      this.user = user;
66      this.agg = agg;
67      this.registry = agg.getMetricsRegistry();
68  
69      this.userNamePrefix = "user_" + user + "_metric_";
70  
71      hashCode = userNamePrefix.hashCode();
72  
73      userGetKey = userNamePrefix + MetricsRegionServerSource.GET_KEY;
74      userScanTimeKey = userNamePrefix + MetricsRegionServerSource.SCAN_TIME_KEY;
75      userPutKey = userNamePrefix + MetricsRegionServerSource.MUTATE_KEY;
76      userDeleteKey = userNamePrefix + MetricsRegionServerSource.DELETE_KEY;
77      userIncrementKey = userNamePrefix + MetricsRegionServerSource.INCREMENT_KEY;
78      userAppendKey = userNamePrefix + MetricsRegionServerSource.APPEND_KEY;
79      userReplayKey = userNamePrefix + MetricsRegionServerSource.REPLAY_KEY;
80  
81      agg.register(this);
82    }
83  
84    @Override
85    public void register() {
86      synchronized (this) {
87        getHisto = registry.newTimeHistogram(userGetKey);
88        scanTimeHisto = registry.newTimeHistogram(userScanTimeKey);
89        putHisto = registry.newTimeHistogram(userPutKey);
90        deleteHisto = registry.newTimeHistogram(userDeleteKey);
91        incrementHisto = registry.newTimeHistogram(userIncrementKey);
92        appendHisto = registry.newTimeHistogram(userAppendKey);
93        replayHisto = registry.newTimeHistogram(userReplayKey);
94      }
95    }
96  
97    @Override
98    public void deregister() {
99      boolean wasClosed = closed.getAndSet(true);
100 
101     // Has someone else already closed this for us?
102     if (wasClosed) {
103       return;
104     }
105 
106     if (LOG.isDebugEnabled()) {
107       LOG.debug("Removing user Metrics for user: " + user);
108     }
109 
110     synchronized (this) {
111       registry.removeHistogramMetrics(userGetKey);
112       registry.removeHistogramMetrics(userScanTimeKey);
113       registry.removeHistogramMetrics(userPutKey);
114       registry.removeHistogramMetrics(userDeleteKey);
115       registry.removeHistogramMetrics(userIncrementKey);
116       registry.removeHistogramMetrics(userAppendKey);
117       registry.removeHistogramMetrics(userReplayKey);
118     }
119   }
120 
121   @Override
122   public String getUser() {
123     return user;
124   }
125 
126   @Override
127   public int compareTo(MetricsUserSource source) {
128     if (source == null) {
129       return -1;
130     }
131     if (!(source instanceof MetricsUserSourceImpl)) {
132       return -1;
133     }
134 
135     MetricsUserSourceImpl impl = (MetricsUserSourceImpl) source;
136 
137     return Long.compare(hashCode, impl.hashCode);
138   }
139 
140   @Override
141   public int hashCode() {
142     return hashCode;
143   }
144 
145   @Override
146   public boolean equals(Object obj) {
147     return obj == this ||
148         (obj instanceof MetricsUserSourceImpl && compareTo((MetricsUserSourceImpl) obj) == 0);
149   }
150 
151   void snapshot(MetricsRecordBuilder mrb, boolean ignored) {
152     // If there is a close that started be double extra sure
153     // that we're not getting any locks and not putting data
154     // into the metrics that should be removed. So early out
155     // before even getting the lock.
156     if (closed.get()) {
157       return;
158     }
159 
160     // Grab the read
161     // This ensures that removes of the metrics
162     // can't happen while we are putting them back in.
163     synchronized (this) {
164 
165       // It's possible that a close happened between checking
166       // the closed variable and getting the lock.
167       if (closed.get()) {
168         return;
169       }
170     }
171   }
172 
173   @Override
174   public void updatePut(long t) {
175     putHisto.add(t);
176   }
177 
178   @Override
179   public void updateDelete(long t) {
180     deleteHisto.add(t);
181   }
182 
183   @Override
184   public void updateGet(long t) {
185     getHisto.add(t);
186   }
187 
188   @Override
189   public void updateIncrement(long t) {
190     incrementHisto.add(t);
191   }
192 
193   @Override
194   public void updateAppend(long t) {
195     appendHisto.add(t);
196   }
197 
198   @Override
199   public void updateReplay(long t) {
200     replayHisto.add(t);
201   }
202 
203   @Override
204   public void updateScanTime(long t) {
205     scanTimeHisto.add(t);
206   }
207 }