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 */
018package org.apache.hadoop.hbase.namequeues;
019
020import java.util.ArrayList;
021import java.util.List;
022import org.apache.commons.lang3.StringUtils;
023import org.apache.hadoop.hbase.util.Addressing;
024import org.apache.yetus.audience.InterfaceAudience;
025
026import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos;
027import org.apache.hadoop.hbase.shaded.protobuf.generated.TooSlowLog;
028
029/**
030 * Event Handler utility class
031 */
032@InterfaceAudience.Private
033public class LogHandlerUtils {
034
035  private static int getTotalFiltersCount(AdminProtos.SlowLogResponseRequest request) {
036    int totalFilters = 0;
037    if (StringUtils.isNotEmpty(request.getRegionName())) {
038      totalFilters++;
039    }
040    if (StringUtils.isNotEmpty(request.getTableName())) {
041      totalFilters++;
042    }
043    if (StringUtils.isNotEmpty(request.getClientAddress())) {
044      totalFilters++;
045    }
046    if (StringUtils.isNotEmpty(request.getUserName())) {
047      totalFilters++;
048    }
049    return totalFilters;
050  }
051
052  private static List<TooSlowLog.SlowLogPayload> filterLogs(
053    AdminProtos.SlowLogResponseRequest request, List<TooSlowLog.SlowLogPayload> slowLogPayloadList,
054    int totalFilters) {
055    List<TooSlowLog.SlowLogPayload> filteredSlowLogPayloads = new ArrayList<>();
056    final String regionName =
057      StringUtils.isNotEmpty(request.getRegionName()) ? request.getRegionName() : null;
058    final String tableName =
059      StringUtils.isNotEmpty(request.getTableName()) ? request.getTableName() : null;
060    final String clientAddress =
061      StringUtils.isNotEmpty(request.getClientAddress()) ? request.getClientAddress() : null;
062    final String userName =
063      StringUtils.isNotEmpty(request.getUserName()) ? request.getUserName() : null;
064    for (TooSlowLog.SlowLogPayload slowLogPayload : slowLogPayloadList) {
065      int totalFilterMatches = 0;
066      if (slowLogPayload.getRegionName().equals(regionName)) {
067        totalFilterMatches++;
068      }
069      if (tableName != null && slowLogPayload.getRegionName().startsWith(tableName)) {
070        totalFilterMatches++;
071      }
072      if (isClientAddressMatched(slowLogPayload, clientAddress)) {
073        totalFilterMatches++;
074      }
075      if (slowLogPayload.getUserName().equals(userName)) {
076        totalFilterMatches++;
077      }
078      if (
079        request.hasFilterByOperator() && request.getFilterByOperator()
080          .equals(AdminProtos.SlowLogResponseRequest.FilterByOperator.AND)
081      ) {
082        // Filter by AND operator
083        if (totalFilterMatches == totalFilters) {
084          filteredSlowLogPayloads.add(slowLogPayload);
085        }
086      } else {
087        // Filter by OR operator
088        if (totalFilterMatches > 0) {
089          filteredSlowLogPayloads.add(slowLogPayload);
090        }
091      }
092    }
093    return filteredSlowLogPayloads;
094  }
095
096  private static boolean isClientAddressMatched(TooSlowLog.SlowLogPayload slowLogPayload,
097    String clientAddress) {
098    String clientAddressInPayload = slowLogPayload.getClientAddress();
099    int portPos = clientAddressInPayload.lastIndexOf(Addressing.HOSTNAME_PORT_SEPARATOR);
100    if (portPos < 1) {
101      return clientAddressInPayload.equals(clientAddress);
102    }
103    return clientAddressInPayload.equals(clientAddress)
104      || clientAddressInPayload.substring(0, portPos).equals(clientAddress);
105  }
106
107  public static List<TooSlowLog.SlowLogPayload> getFilteredLogs(
108    AdminProtos.SlowLogResponseRequest request, List<TooSlowLog.SlowLogPayload> logPayloadList) {
109    int totalFilters = getTotalFiltersCount(request);
110    if (totalFilters > 0) {
111      logPayloadList = filterLogs(request, logPayloadList, totalFilters);
112    }
113    int limit = Math.min(request.getLimit(), logPayloadList.size());
114    return logPayloadList.subList(0, limit);
115  }
116
117}