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