Skip to content

Commit

Permalink
HBASE-27536: improve slowlog payload
Browse files Browse the repository at this point in the history
  • Loading branch information
Ray Mattingly committed Jan 6, 2023
1 parent dcfde79 commit dff72fb
Show file tree
Hide file tree
Showing 7 changed files with 315 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import org.apache.hbase.thirdparty.com.google.gson.JsonObject;
import org.apache.hbase.thirdparty.com.google.gson.JsonSerializer;

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

/**
* Slow/Large Log payload for hbase-client, to be used by Admin API get_slow_responses and
* get_large_responses
Expand Down Expand Up @@ -71,6 +73,10 @@ final public class OnlineLogRecord extends LogEntry {
private final int multiGetsCount;
private final int multiMutationsCount;
private final int multiServiceCalls;
private final ClientProtos.Scan scan;
private final ClientProtos.MultiRequest multi;
private final ClientProtos.Get get;
private final ClientProtos.MutationProto mutate;

public long getStartTime() {
return startTime;
Expand Down Expand Up @@ -128,11 +134,29 @@ public int getMultiServiceCalls() {
return multiServiceCalls;
}

public ClientProtos.Scan getScan() {
return scan;
}

public ClientProtos.MultiRequest getMulti() {
return multi;
}

public ClientProtos.Get getGet() {
return get;
}

public ClientProtos.MutationProto getMutate() {
return mutate;
}

private OnlineLogRecord(final long startTime, final int processingTime, final int queueTime,
final long responseSize, final String clientAddress, final String serverClass,
final String methodName, final String callDetails, final String param, final String regionName,
final String userName, final int multiGetsCount, final int multiMutationsCount,
final int multiServiceCalls) {
final int multiServiceCalls, final ClientProtos.Scan scan,
final ClientProtos.MultiRequest multi, final ClientProtos.Get get,
final ClientProtos.MutationProto mutate) {
this.startTime = startTime;
this.processingTime = processingTime;
this.queueTime = queueTime;
Expand All @@ -147,6 +171,10 @@ private OnlineLogRecord(final long startTime, final int processingTime, final in
this.multiGetsCount = multiGetsCount;
this.multiMutationsCount = multiMutationsCount;
this.multiServiceCalls = multiServiceCalls;
this.scan = scan;
this.multi = multi;
this.get = get;
this.mutate = mutate;
}

public static class OnlineLogRecordBuilder {
Expand All @@ -164,6 +192,10 @@ public static class OnlineLogRecordBuilder {
private int multiGetsCount;
private int multiMutationsCount;
private int multiServiceCalls;
private ClientProtos.Scan scan = null;
private ClientProtos.MultiRequest multi = null;
private ClientProtos.Get get = null;
private ClientProtos.MutationProto mutate = null;

public OnlineLogRecordBuilder setStartTime(long startTime) {
this.startTime = startTime;
Expand Down Expand Up @@ -235,10 +267,30 @@ public OnlineLogRecordBuilder setMultiServiceCalls(int multiServiceCalls) {
return this;
}

public OnlineLogRecordBuilder setScan(ClientProtos.Scan scan) {
this.scan = scan;
return this;
}

public OnlineLogRecordBuilder setMulti(ClientProtos.MultiRequest multi) {
this.multi = multi;
return this;
}

public OnlineLogRecordBuilder setGet(ClientProtos.Get get) {
this.get = get;
return this;
}

public OnlineLogRecordBuilder setMutate(ClientProtos.MutationProto mutate) {
this.mutate = mutate;
return this;
}

public OnlineLogRecord build() {
return new OnlineLogRecord(startTime, processingTime, queueTime, responseSize, clientAddress,
serverClass, methodName, callDetails, param, regionName, userName, multiGetsCount,
multiMutationsCount, multiServiceCalls);
multiMutationsCount, multiServiceCalls, scan, multi, get, mutate);
}
}

Expand All @@ -261,15 +313,17 @@ public boolean equals(Object o) {
.append(multiServiceCalls, that.multiServiceCalls).append(clientAddress, that.clientAddress)
.append(serverClass, that.serverClass).append(methodName, that.methodName)
.append(callDetails, that.callDetails).append(param, that.param)
.append(regionName, that.regionName).append(userName, that.userName).isEquals();
.append(regionName, that.regionName).append(userName, that.userName).append(scan, that.scan)
.append(multi, that.multi).append(get, that.get).append(mutate, that.mutate).isEquals();
}

@Override
public int hashCode() {
return new HashCodeBuilder(17, 37).append(startTime).append(processingTime).append(queueTime)
.append(responseSize).append(clientAddress).append(serverClass).append(methodName)
.append(callDetails).append(param).append(regionName).append(userName).append(multiGetsCount)
.append(multiMutationsCount).append(multiServiceCalls).toHashCode();
.append(multiMutationsCount).append(multiServiceCalls).append(scan).append(multi).append(get)
.append(mutate).toHashCode();
}

@Override
Expand All @@ -286,7 +340,8 @@ public String toString() {
.append("callDetails", callDetails).append("param", param).append("regionName", regionName)
.append("userName", userName).append("multiGetsCount", multiGetsCount)
.append("multiMutationsCount", multiMutationsCount)
.append("multiServiceCalls", multiServiceCalls).toString();
.append("multiServiceCalls", multiServiceCalls).append("scan", scan).append("multi", multi)
.append("get", get).append("mutate", mutate).toString();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.yetus.audience.InterfaceAudience;

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

/**
* SlowLog params object that contains detailed info as params and region name : to be used for
* filter purpose
Expand All @@ -32,15 +34,63 @@ public class SlowLogParams {

private final String regionName;
private final String params;
private final ClientProtos.Scan scan;
private final ClientProtos.MultiRequest multi;
private final ClientProtos.Get get;
private final ClientProtos.MutationProto mutate;

public SlowLogParams(String regionName, String params, ClientProtos.Scan scan) {
this.regionName = regionName;
this.params = params;
this.scan = scan;
this.multi = null;
this.get = null;
this.mutate = null;
}

public SlowLogParams(String regionName, String params, ClientProtos.MultiRequest multi) {
this.regionName = regionName;
this.params = params;
this.scan = null;
this.multi = multi;
this.get = null;
this.mutate = null;
}

public SlowLogParams(String regionName, String params, ClientProtos.Get get) {
this.regionName = regionName;
this.params = params;
this.scan = null;
this.multi = null;
this.get = get;
this.mutate = null;
}

public SlowLogParams(String regionName, String params, ClientProtos.MutationProto mutate) {
this.regionName = regionName;
this.params = params;
this.scan = null;
this.multi = null;
this.get = null;
this.mutate = mutate;
}

public SlowLogParams(String regionName, String params) {
this.regionName = regionName;
this.params = params;
this.scan = null;
this.multi = null;
this.get = null;
this.mutate = null;
}

public SlowLogParams(String params) {
this.regionName = StringUtils.EMPTY;
this.params = params;
this.scan = null;
this.multi = null;
this.get = null;
this.mutate = null;
}

public String getRegionName() {
Expand All @@ -51,9 +101,26 @@ public String getParams() {
return params;
}

public ClientProtos.Scan getScan() {
return scan;
}

public ClientProtos.MultiRequest getMulti() {
return multi;
}

public ClientProtos.Get getGet() {
return get;
}

public ClientProtos.MutationProto getMutate() {
return mutate;
}

@Override
public String toString() {
return new ToStringBuilder(this).append("regionName", regionName).append("params", params)
.append("scan", scan).append("multi", multi).append("get", get).append("mutate", mutate)
.toString();
}

Expand All @@ -67,11 +134,13 @@ public boolean equals(Object o) {
}
SlowLogParams that = (SlowLogParams) o;
return new EqualsBuilder().append(regionName, that.regionName).append(params, that.params)
.isEquals();
.append(scan, that.scan).append(multi, that.multi).append(get, that.get)
.append(mutate, that.mutate).isEquals();
}

@Override
public int hashCode() {
return new HashCodeBuilder(17, 37).append(regionName).append(params).toHashCode();
return new HashCodeBuilder(17, 37).append(regionName).append(params).append(scan).append(multi)
.append(get).append(mutate).toHashCode();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@
import org.apache.hadoop.hbase.util.VersionInfo;
import org.apache.hadoop.ipc.RemoteException;
import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.hbase.thirdparty.com.google.common.io.ByteStreams;
import org.apache.hbase.thirdparty.com.google.gson.JsonArray;
Expand Down Expand Up @@ -229,6 +231,8 @@
@InterfaceAudience.Private // TODO: some clients (Hive, etc) use this class
public final class ProtobufUtil {

private static final Logger LOG = LoggerFactory.getLogger(ProtobufUtil.class.getName());

private ProtobufUtil() {
}

Expand Down Expand Up @@ -2139,41 +2143,62 @@ private static String getStringForByteString(ByteString bs) {

/**
* Return SlowLogParams to maintain recent online slowlog responses
* @param message Message object {@link Message}
* @param message Message object {@link Message}
* @param slowLogOperationMessagePayloadEnabled whether to include the {@link Message} in the
* payload
* @return SlowLogParams with regionName(for filter queries) and params
*/
public static SlowLogParams getSlowLogParams(Message message) {
public static SlowLogParams getSlowLogParams(Message message,
boolean slowLogOperationMessagePayloadEnabled) {
if (message == null) {
return null;
}
if (message instanceof ScanRequest) {
ScanRequest scanRequest = (ScanRequest) message;
String regionName = getStringForByteString(scanRequest.getRegion().getValue());
String params = TextFormat.shortDebugString(message);
return new SlowLogParams(regionName, params);
if (slowLogOperationMessagePayloadEnabled) {
return new SlowLogParams(regionName, params, scanRequest.getScan());
} else {
return new SlowLogParams(regionName, params);
}
} else if (message instanceof MutationProto) {
MutationProto mutationProto = (MutationProto) message;
String params = "type= " + mutationProto.getMutateType().toString();
return new SlowLogParams(params);
if (slowLogOperationMessagePayloadEnabled) {
return new SlowLogParams(null, params, mutationProto);
} else {
return new SlowLogParams(params);
}
} else if (message instanceof GetRequest) {
GetRequest getRequest = (GetRequest) message;
String regionName = getStringForByteString(getRequest.getRegion().getValue());
String params =
"region= " + regionName + ", row= " + getStringForByteString(getRequest.getGet().getRow());
return new SlowLogParams(regionName, params);
if (slowLogOperationMessagePayloadEnabled) {
return new SlowLogParams(regionName, params, getRequest.getGet());
} else {
return new SlowLogParams(regionName, params);
}
} else if (message instanceof MultiRequest) {
MultiRequest multiRequest = (MultiRequest) message;
int actionsCount = multiRequest.getRegionActionList().stream()
.mapToInt(ClientProtos.RegionAction::getActionCount).sum();
RegionAction actions = multiRequest.getRegionActionList().get(0);
String regionName = getStringForByteString(actions.getRegion().getValue());
String params = "region= " + regionName + ", for " + actionsCount + " action(s)";
return new SlowLogParams(regionName, params);
String params = getShortTextFormat(multiRequest);
if (slowLogOperationMessagePayloadEnabled) {
return new SlowLogParams(regionName, params, multiRequest);
} else {
return new SlowLogParams(regionName, params);
}
} else if (message instanceof MutateRequest) {
MutateRequest mutateRequest = (MutateRequest) message;
String regionName = getStringForByteString(mutateRequest.getRegion().getValue());
String params = "region= " + regionName;
return new SlowLogParams(regionName, params);
if (slowLogOperationMessagePayloadEnabled) {
return new SlowLogParams(regionName, params, mutateRequest.getMutation());
} else {
return new SlowLogParams(regionName, params);
}
} else if (message instanceof CoprocessorServiceRequest) {
CoprocessorServiceRequest coprocessorServiceRequest = (CoprocessorServiceRequest) message;
String params = "coprocessorService= " + coprocessorServiceRequest.getCall().getServiceName()
Expand Down Expand Up @@ -3376,7 +3401,9 @@ private static LogEntry getSlowLogRecord(final TooSlowLog.SlowLogPayload slowLog
.setQueueTime(slowLogPayload.getQueueTime()).setRegionName(slowLogPayload.getRegionName())
.setResponseSize(slowLogPayload.getResponseSize())
.setServerClass(slowLogPayload.getServerClass()).setStartTime(slowLogPayload.getStartTime())
.setUserName(slowLogPayload.getUserName()).build();
.setUserName(slowLogPayload.getUserName()).setScan(slowLogPayload.getScan())
.setMulti(slowLogPayload.getMulti()).setGet(slowLogPayload.getGet())
.setMutate(slowLogPayload.getMutate()).build();
return onlineLogRecord;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1564,6 +1564,10 @@ public enum OperationStatusCode {
// Default 10 mins.
public static final int DEFAULT_SLOW_LOG_SYS_TABLE_CHORE_DURATION = 10 * 60 * 1000;

public static final String SLOW_LOG_OPERATION_MESSAGE_PAYLOAD_ENABLED =
"hbase.slowlog.operation.message.payload.enabled";
public static final boolean SLOW_LOG_OPERATION_MESSAGE_PAYLOAD_ENABLED_DEFAULT = false;

public static final String SHELL_TIMESTAMP_FORMAT_EPOCH_KEY =
"hbase.shell.timestamp.format.epoch";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ option java_outer_classname = "TooSlowLog";
option java_generate_equals_and_hash = true;
option optimize_for = SPEED;

import "client/Client.proto";

message SlowLogPayload {
required int64 start_time = 1;
required int32 processing_time = 2;
Expand All @@ -43,6 +45,10 @@ message SlowLogPayload {
optional int32 multi_mutations = 13 [default = 0];
optional int32 multi_service_calls = 14 [default = 0];
required Type type = 15;
optional Scan scan = 16;
optional MultiRequest multi = 17;
optional Get get = 18;
optional MutationProto mutate = 19;

// SLOW_LOG is RPC call slow in nature whereas LARGE_LOG is RPC call quite large.
// Majority of times, slow logs are also large logs and hence, ALL is combination of
Expand Down
Loading

0 comments on commit dff72fb

Please sign in to comment.