001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.apache.hadoop.hbase.regionserver;
020
021import java.io.IOException;
022import java.net.InetAddress;
023import java.util.Optional;
024import org.apache.hadoop.conf.Configuration;
025import org.apache.hadoop.hbase.CompatibilitySingletonFactory;
026import org.apache.hadoop.hbase.ipc.RpcServer;
027import org.apache.hadoop.hbase.security.User;
028import org.apache.hadoop.hbase.security.UserProvider;
029import org.apache.hadoop.hbase.util.LossyCounting;
030import org.apache.yetus.audience.InterfaceAudience;
031
032@InterfaceAudience.Private
033public class MetricsUserAggregateImpl implements MetricsUserAggregate{
034
035  /** Provider for mapping principal names to Users */
036  private final UserProvider userProvider;
037
038  private final MetricsUserAggregateSource source;
039  private final LossyCounting<MetricsUserSource> userMetricLossyCounting;
040
041  public MetricsUserAggregateImpl(Configuration conf) {
042    source = CompatibilitySingletonFactory.getInstance(MetricsRegionServerSourceFactory.class)
043        .getUserAggregate();
044    userMetricLossyCounting = new LossyCounting<>("userMetrics", conf, source::deregister);
045    this.userProvider = UserProvider.instantiate(conf);
046  }
047
048  /**
049   * Returns the active user to which authorization checks should be applied.
050   * If we are in the context of an RPC call, the remote user is used,
051   * otherwise the currently logged in user is used.
052   */
053  private String getActiveUser() {
054    Optional<User> user = RpcServer.getRequestUser();
055    if (!user.isPresent()) {
056      // for non-rpc handling, fallback to system user
057      try {
058        user = Optional.of(userProvider.getCurrent());
059      } catch (IOException ignore) {
060      }
061    }
062    return user.map(User::getShortName).orElse(null);
063  }
064
065  @Override
066  public MetricsUserAggregateSource getSource() {
067    return source;
068  }
069
070  @Override
071  public void updatePut(long t) {
072    String user = getActiveUser();
073    if (user != null) {
074      MetricsUserSource userSource = getOrCreateMetricsUser(user);
075      userSource.updatePut(t);
076      incrementClientWriteMetrics(userSource);
077    }
078
079  }
080
081  private String getClient() {
082    Optional<InetAddress> ipOptional = RpcServer.getRemoteAddress();
083    return ipOptional.map(InetAddress::getHostName).orElse(null);
084  }
085
086  private void incrementClientReadMetrics(MetricsUserSource userSource) {
087    String client = getClient();
088    if (client != null && userSource != null) {
089      userSource.getOrCreateMetricsClient(client).incrementReadRequest();
090    }
091  }
092
093  private void incrementFilteredReadRequests(MetricsUserSource userSource) {
094    String client = getClient();
095    if (client != null && userSource != null) {
096      userSource.getOrCreateMetricsClient(client).incrementFilteredReadRequests();
097    }
098  }
099
100  private void incrementClientWriteMetrics(MetricsUserSource userSource) {
101    String client = getClient();
102    if (client != null && userSource != null) {
103      userSource.getOrCreateMetricsClient(client).incrementWriteRequest();
104    }
105  }
106
107  @Override
108  public void updateDelete(long t) {
109    String user = getActiveUser();
110    if (user != null) {
111      MetricsUserSource userSource = getOrCreateMetricsUser(user);
112      userSource.updateDelete(t);
113      incrementClientWriteMetrics(userSource);
114    }
115  }
116
117  @Override
118  public void updateGet(long t) {
119    String user = getActiveUser();
120    if (user != null) {
121      MetricsUserSource userSource = getOrCreateMetricsUser(user);
122      userSource.updateGet(t);
123    }
124  }
125
126  @Override
127  public void updateIncrement(long t) {
128    String user = getActiveUser();
129    if (user != null) {
130      MetricsUserSource userSource = getOrCreateMetricsUser(user);
131      userSource.updateIncrement(t);
132      incrementClientWriteMetrics(userSource);
133    }
134  }
135
136  @Override
137  public void updateAppend(long t) {
138    String user = getActiveUser();
139    if (user != null) {
140      MetricsUserSource userSource = getOrCreateMetricsUser(user);
141      userSource.updateAppend(t);
142      incrementClientWriteMetrics(userSource);
143    }
144  }
145
146  @Override
147  public void updateReplay(long t) {
148    String user = getActiveUser();
149    if (user != null) {
150      MetricsUserSource userSource = getOrCreateMetricsUser(user);
151      userSource.updateReplay(t);
152      incrementClientWriteMetrics(userSource);
153    }
154  }
155
156  @Override
157  public void updateScanTime(long t) {
158    String user = getActiveUser();
159    if (user != null) {
160      MetricsUserSource userSource = getOrCreateMetricsUser(user);
161      userSource.updateScanTime(t);
162    }
163  }
164
165  @Override public void updateFilteredReadRequests() {
166    String user = getActiveUser();
167    if (user != null) {
168      MetricsUserSource userSource = getOrCreateMetricsUser(user);
169      incrementFilteredReadRequests(userSource);
170    }
171  }
172
173  @Override public void updateReadRequestCount() {
174    String user = getActiveUser();
175    if (user != null) {
176      MetricsUserSource userSource = getOrCreateMetricsUser(user);
177      incrementClientReadMetrics(userSource);
178    }
179  }
180
181  private MetricsUserSource getOrCreateMetricsUser(String user) {
182    MetricsUserSource userSource = source.getOrCreateMetricsUser(user);
183    userMetricLossyCounting.add(userSource);
184    return userSource;
185  }
186}