Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ interface ClientMetrics {
long getWriteRequestsCount();

long getFilteredReadRequestsCount();

String getHostAddress();

String getUserName();

String getClientVersion();

String getServiceName();
}

/** Returns the user name */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ public static UserMetrics toUserMetrics(ClusterStatusProtos.UserLoad userLoad) {
userLoad.getClientMetricsList().stream()
.map(clientMetrics -> new ClientMetricsImpl(clientMetrics.getHostName(),
clientMetrics.getReadRequestsCount(), clientMetrics.getWriteRequestsCount(),
clientMetrics.getFilteredRequestsCount()))
clientMetrics.getFilteredRequestsCount(), clientMetrics.getHostAddress(),
clientMetrics.getUserName(), clientMetrics.getServiceName(),
clientMetrics.getClientVersion()))
.forEach(builder::addClientMetris);
return builder.build();
}
Expand All @@ -49,7 +51,10 @@ public static ClusterStatusProtos.UserLoad toUserMetrics(UserMetrics userMetrics
.setHostName(clientMetrics.getHostName())
.setWriteRequestsCount(clientMetrics.getWriteRequestsCount())
.setReadRequestsCount(clientMetrics.getReadRequestsCount())
.setFilteredRequestsCount(clientMetrics.getFilteredReadRequestsCount()).build())
.setFilteredRequestsCount(clientMetrics.getFilteredReadRequestsCount())
.setHostAddress(clientMetrics.getHostAddress()).setUserName(clientMetrics.getUserName())
.setServiceName(clientMetrics.getServiceName())
.setClientVersion(clientMetrics.getClientVersion()).build())
.forEach(builder::addClientMetrics);
return builder.build();
}
Expand Down Expand Up @@ -79,13 +84,22 @@ public static class ClientMetricsImpl implements UserMetrics.ClientMetrics {
private final String hostName;
private final long readRequestCount;
private final long writeRequestCount;
private final String hostAddress;
private final String userName;
private final String serviceName;
private final String clientVersion;

public ClientMetricsImpl(String hostName, long readRequest, long writeRequest,
long filteredReadRequestsCount) {
long filteredReadRequestsCount, String hostAddress, String userName, String serviceName,
String clientVersion) {
this.hostName = hostName;
this.readRequestCount = readRequest;
this.writeRequestCount = writeRequest;
this.filteredReadRequestsCount = filteredReadRequestsCount;
this.hostAddress = hostAddress != null ? hostAddress : "Unknown";
this.userName = userName != null ? userName : "Unknown";
this.serviceName = serviceName != null ? serviceName : "Unknown";
this.clientVersion = clientVersion != null ? clientVersion : "Unknown";
}

@Override
Expand All @@ -107,6 +121,26 @@ public long getWriteRequestsCount() {
public long getFilteredReadRequestsCount() {
return filteredReadRequestsCount;
}

@Override
public String getHostAddress() {
return hostAddress;
}

@Override
public String getUserName() {
return userName;
}

@Override
public String getServiceName() {
return serviceName;
}

@Override
public String getClientVersion() {
return clientVersion;
}
}

private static class UserMetricsImpl implements UserMetrics {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hbase;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import org.apache.hadoop.hbase.testclassification.ClientTests;
import org.apache.hadoop.hbase.testclassification.SmallTests;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

import org.apache.hadoop.hbase.shaded.protobuf.generated.ClusterStatusProtos;

@Tag(ClientTests.TAG)
@Tag(SmallTests.TAG)
public class TestUserMetricsBuilder {

@Test
public void testRoundTripPreservesClientConnectionFields() {
// Build a user metrics snapshot with all client-connection identity fields populated.
UserMetrics userMetrics = UserMetricsBuilder.newBuilder(Bytes.toBytes("alice"))
.addClientMetris(new UserMetricsBuilder.ClientMetricsImpl("clientHost", 11L, 22L, 3L,
"10.1.1.1", "alice", "ClientService", "1.2.3"))
.build();

// Convert to protobuf and back; UI/server paths rely on this round-trip preserving fields.
ClusterStatusProtos.UserLoad userLoad = UserMetricsBuilder.toUserMetrics(userMetrics);
UserMetrics converted = UserMetricsBuilder.toUserMetrics(userLoad);

UserMetrics.ClientMetrics clientMetrics = converted.getClientMetrics().get("clientHost");
assertNotNull(clientMetrics);
assertEquals("10.1.1.1", clientMetrics.getHostAddress());
assertEquals("alice", clientMetrics.getUserName());
assertEquals("ClientService", clientMetrics.getServiceName());
assertEquals("1.2.3", clientMetrics.getClientVersion());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ interface ClientMetrics {
void incrementFilteredReadRequests();

long getFilteredReadRequests();

String getHostAddress();

String getUserName();

String getClientVersion();

String getServiceName();
}

String getUser();
Expand Down Expand Up @@ -77,5 +85,6 @@ interface ClientMetrics {
* @param hostName hostname of the client
* @return Instance of ClientMetrics
*/
ClientMetrics getOrCreateMetricsClient(String hostName);
ClientMetrics getOrCreateMetricsClient(String hostName, String hostAddress, String userName,
String clientVersion, String serviceName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,18 @@ static class ClientMetricsImpl implements ClientMetrics {
final LongAdder readRequestsCount = new LongAdder();
final LongAdder writeRequestsCount = new LongAdder();
final LongAdder filteredRequestsCount = new LongAdder();
private final String hostAddress;
private final String userName;
private final String clientVersion;
private final String serviceName;

public ClientMetricsImpl(String hostName) {
public ClientMetricsImpl(String hostName, String hostAddress, String userName,
String clientVersion, String serviceName) {
this.hostName = hostName;
this.hostAddress = hostAddress != null ? hostAddress : "Unknown";
this.userName = userName != null ? userName : "Unknown";
this.clientVersion = clientVersion != null ? clientVersion : "Unknown";
this.serviceName = serviceName != null ? serviceName : "Unknown";
}

@Override
Expand Down Expand Up @@ -109,6 +118,26 @@ public void incrementFilteredReadRequests() {
public long getFilteredReadRequests() {
return filteredRequestsCount.sum();
}

@Override
public String getHostAddress() {
return hostAddress;
}

@Override
public String getUserName() {
return userName;
}

@Override
public String getClientVersion() {
return clientVersion;
}

@Override
public String getServiceName() {
return serviceName;
}
}

public MetricsUserSourceImpl(String user, MetricsUserAggregateSourceImpl agg) {
Expand Down Expand Up @@ -278,12 +307,13 @@ public Map<String, ClientMetrics> getClientMetrics() {
}

@Override
public ClientMetrics getOrCreateMetricsClient(String client) {
public ClientMetrics getOrCreateMetricsClient(String client, String hostAddress, String userName,
String clientVersion, String serviceName) {
ClientMetrics source = clientMetricsMap.get(client);
if (source != null) {
return source;
}
source = new ClientMetricsImpl(client);
source = new ClientMetricsImpl(client, hostAddress, userName, clientVersion, serviceName);
ClientMetrics prev = clientMetricsMap.putIfAbsent(client, source);
if (prev != null) {
return prev;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,11 @@ public enum Field {
MAX_HEAP_SIZE("MHEAP", "Max Heap Size", false, false, FieldValueType.SIZE),
CLIENT_COUNT("#CLIENT", "Client Count", false, false, FieldValueType.INTEGER),
USER_COUNT("#USER", "User Count", false, false, FieldValueType.INTEGER),
CLIENT("CLIENT", "Client Hostname", true, true, FieldValueType.STRING);
CLIENT("CLIENT", "Client Hostname", true, true, FieldValueType.STRING),
HOST_ADDRESS("HADDR", "Client Host Address", true, true, FieldValueType.STRING),
CLIENT_VERSION("CVER", "Client Version", true, true, FieldValueType.STRING),
USER_NAME("USER", "User Name", true, true, FieldValueType.STRING),
SERVICE_NAME("SVC", "Service Name", true, true, FieldValueType.STRING);

private final String header;
private final String description;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ public final class ClientModeStrategy implements ModeStrategy {
new FieldInfo(Field.REQUEST_COUNT_PER_SECOND, 10, true),
new FieldInfo(Field.READ_REQUEST_COUNT_PER_SECOND, 10, true),
new FieldInfo(Field.WRITE_REQUEST_COUNT_PER_SECOND, 10, true),
new FieldInfo(Field.FILTERED_READ_REQUEST_COUNT_PER_SECOND, 10, true));
new FieldInfo(Field.FILTERED_READ_REQUEST_COUNT_PER_SECOND, 10, true),
new FieldInfo(Field.HOST_ADDRESS, 0, true), new FieldInfo(Field.USER_NAME, 0, true),
new FieldInfo(Field.CLIENT_VERSION, 0, true), new FieldInfo(Field.SERVICE_NAME, 0, true));
private final Map<String, RequestCountPerSecond> requestCountPerSecondMap = new HashMap<>();

ClientModeStrategy() {
Expand Down Expand Up @@ -145,6 +147,10 @@ Record createRecord(String user, UserMetrics.ClientMetrics clientMetrics,
requestCountPerSecond.getWriteRequestCountPerSecond());
builder.put(Field.FILTERED_READ_REQUEST_COUNT_PER_SECOND,
requestCountPerSecond.getFilteredReadRequestCountPerSecond());
builder.put(Field.HOST_ADDRESS, clientMetrics.getHostAddress());
builder.put(Field.USER_NAME, clientMetrics.getUserName());
builder.put(Field.CLIENT_VERSION, clientMetrics.getClientVersion());
builder.put(Field.SERVICE_NAME, clientMetrics.getServiceName());
builder.put(Field.USER, user);
return builder.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,23 @@ public final class TestUtils {
private TestUtils() {
}

private static final String TEST_USER_FOO = "FOO";
private static final String TEST_USER_BAR = "BAR";
private static final String TEST_HOST_ADDRESS_A = "10.0.0.1";
private static final String TEST_HOST_ADDRESS_B = "10.0.0.2";
private static final String TEST_SERVICE_NAME = "ClientService";
private static final String TEST_CLIENT_VERSION = "test-client-version";

public static ClusterMetrics createDummyClusterMetrics() {
Map<ServerName, ServerMetrics> serverMetricsMap = new HashMap<>();

// host1
List<RegionMetrics> regionMetricsList = new ArrayList<>();
List<UserMetrics> userMetricsList = new ArrayList<>();
userMetricsList.add(createUserMetrics("FOO", 1, 2, 4));
userMetricsList.add(createUserMetrics("BAR", 2, 3, 3));
userMetricsList.add(createUserMetrics(TEST_USER_FOO, 1, 2, 4, TEST_HOST_ADDRESS_A,
TEST_HOST_ADDRESS_B, TEST_CLIENT_VERSION, TEST_SERVICE_NAME));
userMetricsList.add(createUserMetrics(TEST_USER_BAR, 2, 3, 3, TEST_HOST_ADDRESS_A,
TEST_HOST_ADDRESS_B, TEST_CLIENT_VERSION, TEST_SERVICE_NAME));
regionMetricsList.add(createRegionMetrics("table1,,1.00000000000000000000000000000000.", 100,
50, 100, new Size(100, Size.Unit.MEGABYTE), new Size(200, Size.Unit.MEGABYTE), 1,
new Size(100, Size.Unit.MEGABYTE), 0.1f, 100, 100, "2019-07-22 00:00:00"));
Expand All @@ -76,8 +85,10 @@ public static ClusterMetrics createDummyClusterMetrics() {
// host2
regionMetricsList.clear();
userMetricsList.clear();
userMetricsList.add(createUserMetrics("FOO", 5, 7, 3));
userMetricsList.add(createUserMetrics("BAR", 4, 8, 4));
userMetricsList.add(createUserMetrics(TEST_USER_FOO, 5, 7, 3, TEST_HOST_ADDRESS_A,
TEST_HOST_ADDRESS_B, TEST_CLIENT_VERSION, TEST_SERVICE_NAME));
userMetricsList.add(createUserMetrics(TEST_USER_BAR, 4, 8, 4, TEST_HOST_ADDRESS_A,
TEST_HOST_ADDRESS_B, TEST_CLIENT_VERSION, TEST_SERVICE_NAME));
regionMetricsList.add(createRegionMetrics("table1,1,4.00000000000000000000000000000003.", 100,
50, 100, new Size(100, Size.Unit.MEGABYTE), new Size(200, Size.Unit.MEGABYTE), 1,
new Size(100, Size.Unit.MEGABYTE), 0.4f, 50, 100, "2019-07-22 00:00:03"));
Expand Down Expand Up @@ -105,12 +116,15 @@ public static ClusterMetrics createDummyClusterMetrics() {
}

private static UserMetrics createUserMetrics(String user, long readRequestCount,
long writeRequestCount, long filteredReadRequestsCount) {
long writeRequestCount, long filteredReadRequestsCount, String hostAddressA,
String hostAddressB, String clientVersion, String serviceName) {
return UserMetricsBuilder.newBuilder(Bytes.toBytes(user))
.addClientMetris(new UserMetricsBuilder.ClientMetricsImpl("CLIENT_A_" + user,
readRequestCount, writeRequestCount, filteredReadRequestsCount))
readRequestCount, writeRequestCount, filteredReadRequestsCount, hostAddressA, user,
serviceName, clientVersion))
.addClientMetris(new UserMetricsBuilder.ClientMetricsImpl("CLIENT_B_" + user,
readRequestCount, writeRequestCount, filteredReadRequestsCount))
readRequestCount, writeRequestCount, filteredReadRequestsCount, hostAddressB, user,
serviceName, clientVersion))
.build();
}

Expand Down Expand Up @@ -312,10 +326,10 @@ public static void assertRecordsInUserMode(List<Record> records) {
switch (user) {
// readRequestPerSecond and writeRequestPerSecond will be zero
// because there is no change or new metrics during refresh
case "FOO":
case TEST_USER_FOO:
assertRecordInUserMode(record, 0L, 0L, 0L);
break;
case "BAR":
case TEST_USER_BAR:
assertRecordInUserMode(record, 0L, 0L, 0L);
break;
default:
Expand All @@ -331,17 +345,21 @@ public static void assertRecordsInClientMode(List<Record> records) {
switch (client) {
// readRequestPerSecond and writeRequestPerSecond will be zero
// because there is no change or new metrics during refresh
case "CLIENT_A_FOO":
assertRecordInClientMode(record, 0L, 0L, 0L);
case "CLIENT_A_" + TEST_USER_FOO:
assertRecordInClientMode(record, 0L, 0L, 0L, TEST_HOST_ADDRESS_A, TEST_USER_FOO,
TEST_CLIENT_VERSION, TEST_SERVICE_NAME);
break;
case "CLIENT_A_BAR":
assertRecordInClientMode(record, 0L, 0L, 0L);
case "CLIENT_A_" + TEST_USER_BAR:
assertRecordInClientMode(record, 0L, 0L, 0L, TEST_HOST_ADDRESS_A, TEST_USER_BAR,
TEST_CLIENT_VERSION, TEST_SERVICE_NAME);
break;
case "CLIENT_B_FOO":
assertRecordInClientMode(record, 0L, 0L, 0L);
case "CLIENT_B_" + TEST_USER_FOO:
assertRecordInClientMode(record, 0L, 0L, 0L, TEST_HOST_ADDRESS_B, TEST_USER_FOO,
TEST_CLIENT_VERSION, TEST_SERVICE_NAME);
break;
case "CLIENT_B_BAR":
assertRecordInClientMode(record, 0L, 0L, 0L);
case "CLIENT_B_" + TEST_USER_BAR:
assertRecordInClientMode(record, 0L, 0L, 0L, TEST_HOST_ADDRESS_B, TEST_USER_BAR,
TEST_CLIENT_VERSION, TEST_SERVICE_NAME);
break;
default:
fail();
Expand All @@ -351,7 +369,7 @@ public static void assertRecordsInClientMode(List<Record> records) {

private static void assertRecordInUserMode(Record record, long readRequestCountPerSecond,
long writeCountRequestPerSecond, long filteredReadRequestsCount) {
assertThat(record.size(), is(6));
assertThat(record.size(), is(10));
assertThat(record.get(Field.READ_REQUEST_COUNT_PER_SECOND).asLong(),
is(readRequestCountPerSecond));
assertThat(record.get(Field.WRITE_REQUEST_COUNT_PER_SECOND).asLong(),
Expand All @@ -362,14 +380,19 @@ private static void assertRecordInUserMode(Record record, long readRequestCountP
}

private static void assertRecordInClientMode(Record record, long readRequestCountPerSecond,
long writeCountRequestPerSecond, long filteredReadRequestsCount) {
assertThat(record.size(), is(6));
long writeCountRequestPerSecond, long filteredReadRequestsCount, String hostAddress,
String userName, String clientVersion, String serviceName) {
assertThat(record.size(), is(10));
assertThat(record.get(Field.READ_REQUEST_COUNT_PER_SECOND).asLong(),
is(readRequestCountPerSecond));
assertThat(record.get(Field.WRITE_REQUEST_COUNT_PER_SECOND).asLong(),
is(writeCountRequestPerSecond));
assertThat(record.get(Field.FILTERED_READ_REQUEST_COUNT_PER_SECOND).asLong(),
is(filteredReadRequestsCount));
assertThat(record.get(Field.HOST_ADDRESS).asString(), is(hostAddress));
assertThat(record.get(Field.USER_NAME).asString(), is(userName));
assertThat(record.get(Field.CLIENT_VERSION).asString(), is(clientVersion));
assertThat(record.get(Field.SERVICE_NAME).asString(), is(serviceName));
assertThat(record.get(Field.USER_COUNT).asInt(), is(1));
}

Expand Down
Loading