diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/namequeues/LogHandlerUtils.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/namequeues/LogHandlerUtils.java index 1d7dd7ae686..4cd18bf5a69 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/namequeues/LogHandlerUtils.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/namequeues/LogHandlerUtils.java @@ -20,6 +20,7 @@ package org.apache.hadoop.hbase.namequeues; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang3.StringUtils; +import org.apache.hadoop.hbase.util.Addressing; import org.apache.yetus.audience.InterfaceAudience; import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos; @@ -68,7 +69,7 @@ public class LogHandlerUtils { if (tableName != null && slowLogPayload.getRegionName().startsWith(tableName)) { totalFilterMatches++; } - if (slowLogPayload.getClientAddress().equals(clientAddress)) { + if (isClientAddressMatched(slowLogPayload, clientAddress)) { totalFilterMatches++; } if (slowLogPayload.getUserName().equals(userName)) { @@ -92,6 +93,17 @@ public class LogHandlerUtils { return filteredSlowLogPayloads; } + private static boolean isClientAddressMatched(TooSlowLog.SlowLogPayload slowLogPayload, + String clientAddress) { + String clientAddressInPayload = slowLogPayload.getClientAddress(); + int portPos = clientAddressInPayload.lastIndexOf(Addressing.HOSTNAME_PORT_SEPARATOR); + if (portPos < 1) { + return clientAddressInPayload.equals(clientAddress); + } + return clientAddressInPayload.equals(clientAddress) + || clientAddressInPayload.substring(0, portPos).equals(clientAddress); + } + public static List getFilteredLogs( AdminProtos.SlowLogResponseRequest request, List logPayloadList) { int totalFilters = getTotalFiltersCount(request); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/namequeues/TestNamedQueueRecorder.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/namequeues/TestNamedQueueRecorder.java index 909e7fdb7f3..17bdbadc3b0 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/namequeues/TestNamedQueueRecorder.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/namequeues/TestNamedQueueRecorder.java @@ -363,6 +363,60 @@ public class TestNamedQueueRecorder { HBASE_TESTING_UTILITY.waitFor(3000, () -> getSlowLogPayloads(requestSlowLog).size() == 15)); } + @Test + public void testSlowLogFilterWithClientAddress() throws Exception { + Configuration conf = applySlowLogRecorderConf(10); + Constructor constructor = + NamedQueueRecorder.class.getDeclaredConstructor(Configuration.class); + constructor.setAccessible(true); + namedQueueRecorder = constructor.newInstance(conf); + AdminProtos.SlowLogResponseRequest request = + AdminProtos.SlowLogResponseRequest.newBuilder().build(); + Assert.assertEquals(getSlowLogPayloads(request).size(), 0); + + String[] clientAddressArray = new String[] { "[127:1:1:1:1:1:1:1]:1", "[127:1:1:1:1:1:1:1]:2", + "[127:1:1:1:1:1:1:1]:3", "127.0.0.1:1", "127.0.0.1:2" }; + boolean isSlowLog; + boolean isLargeLog; + for (int i = 0; i < 10; i++) { + if (i % 2 == 0) { + isSlowLog = true; + isLargeLog = false; + } else { + isSlowLog = false; + isLargeLog = true; + } + RpcLogDetails rpcLogDetails = getRpcLogDetails("userName_" + (i + 1), + clientAddressArray[i % 5], "class_" + (i + 1), isSlowLog, isLargeLog); + namedQueueRecorder.addRecord(rpcLogDetails); + } + + AdminProtos.SlowLogResponseRequest largeLogRequestIPv6WithPort = + AdminProtos.SlowLogResponseRequest.newBuilder() + .setLogType(AdminProtos.SlowLogResponseRequest.LogType.LARGE_LOG) + .setClientAddress("[127:1:1:1:1:1:1:1]:2").build(); + Assert.assertNotEquals(-1, HBASE_TESTING_UTILITY.waitFor(3000, + () -> getSlowLogPayloads(largeLogRequestIPv6WithPort).size() == 1)); + AdminProtos.SlowLogResponseRequest largeLogRequestIPv6WithoutPort = + AdminProtos.SlowLogResponseRequest.newBuilder() + .setLogType(AdminProtos.SlowLogResponseRequest.LogType.LARGE_LOG) + .setClientAddress("[127:1:1:1:1:1:1:1]").build(); + Assert.assertNotEquals(-1, HBASE_TESTING_UTILITY.waitFor(3000, + () -> getSlowLogPayloads(largeLogRequestIPv6WithoutPort).size() == 3)); + AdminProtos.SlowLogResponseRequest largeLogRequestIPv4WithPort = + AdminProtos.SlowLogResponseRequest.newBuilder() + .setLogType(AdminProtos.SlowLogResponseRequest.LogType.LARGE_LOG) + .setClientAddress("127.0.0.1:1").build(); + Assert.assertNotEquals(-1, HBASE_TESTING_UTILITY.waitFor(3000, + () -> getSlowLogPayloads(largeLogRequestIPv4WithPort).size() == 1)); + AdminProtos.SlowLogResponseRequest largeLogRequestIPv4WithoutPort = + AdminProtos.SlowLogResponseRequest.newBuilder() + .setLogType(AdminProtos.SlowLogResponseRequest.LogType.LARGE_LOG) + .setClientAddress("127.0.0.1").build(); + Assert.assertNotEquals(-1, HBASE_TESTING_UTILITY.waitFor(3000, + () -> getSlowLogPayloads(largeLogRequestIPv4WithoutPort).size() == 2)); + } + @Test public void testConcurrentSlowLogEvents() throws Exception { diff --git a/hbase-shell/src/main/ruby/shell/commands/get_largelog_responses.rb b/hbase-shell/src/main/ruby/shell/commands/get_largelog_responses.rb index 8ed55abfc10..45257df7f17 100644 --- a/hbase-shell/src/main/ruby/shell/commands/get_largelog_responses.rb +++ b/hbase-shell/src/main/ruby/shell/commands/get_largelog_responses.rb @@ -44,6 +44,12 @@ Examples: => get largelog responses only related to meta region hbase> get_largelog_responses '*', {'TABLE_NAME' => 't1'} => get largelog responses only related to t1 table + hbase> get_largelog_responses '*', {'CLIENT_IP' => '192.162.1.40'} + => get largelog responses only related to the given + client IP address + hbase> get_largelog_responses '*', {'CLIENT_IP' => '192.162.1.40:60225'} + => get largelog responses only related to the given + client IP address and port hbase> get_largelog_responses '*', {'CLIENT_IP' => '192.162.1.40:60225', 'LIMIT' => 100} => get largelog responses with given client IP address and get 100 records limit diff --git a/hbase-shell/src/main/ruby/shell/commands/get_slowlog_responses.rb b/hbase-shell/src/main/ruby/shell/commands/get_slowlog_responses.rb index 2dc108b1d68..c53bedc8169 100644 --- a/hbase-shell/src/main/ruby/shell/commands/get_slowlog_responses.rb +++ b/hbase-shell/src/main/ruby/shell/commands/get_slowlog_responses.rb @@ -44,6 +44,12 @@ Examples: => get slowlog responses only related to meta region hbase> get_slowlog_responses '*', {'TABLE_NAME' => 't1'} => get slowlog responses only related to t1 table + hbase> get_slowlog_responses '*', {'CLIENT_IP' => '192.162.1.40'} + => get slowlog responses only related to the given + client IP address + hbase> get_slowlog_responses '*', {'CLIENT_IP' => '192.162.1.40:60225'} + => get slowlog responses only related to the given + client IP address and port hbase> get_slowlog_responses '*', {'CLIENT_IP' => '192.162.1.40:60225', 'LIMIT' => 100} => get slowlog responses with given client IP address and get 100 records limit