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.client; 019 020import java.util.Optional; 021import org.apache.commons.lang3.builder.EqualsBuilder; 022import org.apache.commons.lang3.builder.HashCodeBuilder; 023import org.apache.commons.lang3.builder.ToStringBuilder; 024import org.apache.hadoop.hbase.util.GsonUtil; 025import org.apache.yetus.audience.InterfaceAudience; 026import org.apache.yetus.audience.InterfaceStability; 027 028import org.apache.hbase.thirdparty.com.google.gson.Gson; 029import org.apache.hbase.thirdparty.com.google.gson.JsonObject; 030import org.apache.hbase.thirdparty.com.google.gson.JsonSerializer; 031 032/** 033 * Slow/Large Log payload for hbase-client, to be used by Admin API get_slow_responses and 034 * get_large_responses 035 */ 036@InterfaceAudience.Public 037@InterfaceStability.Evolving 038final public class OnlineLogRecord extends LogEntry { 039 040 // used to convert object to pretty printed format 041 // used by toJsonPrettyPrint() 042 private static final Gson GSON = 043 GsonUtil.createGson().setPrettyPrinting().registerTypeAdapter(OnlineLogRecord.class, 044 (JsonSerializer<OnlineLogRecord>) (slowLogPayload, type, jsonSerializationContext) -> { 045 Gson gson = new Gson(); 046 JsonObject jsonObj = (JsonObject) gson.toJsonTree(slowLogPayload); 047 if (slowLogPayload.getMultiGetsCount() == 0) { 048 jsonObj.remove("multiGetsCount"); 049 } 050 if (slowLogPayload.getMultiMutationsCount() == 0) { 051 jsonObj.remove("multiMutationsCount"); 052 } 053 if (slowLogPayload.getMultiServiceCalls() == 0) { 054 jsonObj.remove("multiServiceCalls"); 055 } 056 if (slowLogPayload.getScan().isPresent()) { 057 jsonObj.add("scan", gson.toJsonTree(slowLogPayload.getScan().get().toMap())); 058 } else { 059 jsonObj.remove("scan"); 060 } 061 return jsonObj; 062 }).create(); 063 064 private final long startTime; 065 private final int processingTime; 066 private final int queueTime; 067 private final long responseSize; 068 private final long blockBytesScanned; 069 private final String clientAddress; 070 private final String serverClass; 071 private final String methodName; 072 private final String callDetails; 073 private final String param; 074 // we don't want to serialize region name, it is just for the filter purpose 075 // hence avoiding deserialization 076 private final transient String regionName; 077 private final String userName; 078 private final int multiGetsCount; 079 private final int multiMutationsCount; 080 private final int multiServiceCalls; 081 private final Optional<Scan> scan; 082 083 public long getStartTime() { 084 return startTime; 085 } 086 087 public int getProcessingTime() { 088 return processingTime; 089 } 090 091 public int getQueueTime() { 092 return queueTime; 093 } 094 095 public long getResponseSize() { 096 return responseSize; 097 } 098 099 /** 100 * Return the amount of block bytes scanned to retrieve the response cells. 101 */ 102 public long getBlockBytesScanned() { 103 return blockBytesScanned; 104 } 105 106 public String getClientAddress() { 107 return clientAddress; 108 } 109 110 public String getServerClass() { 111 return serverClass; 112 } 113 114 public String getMethodName() { 115 return methodName; 116 } 117 118 public String getCallDetails() { 119 return callDetails; 120 } 121 122 public String getParam() { 123 return param; 124 } 125 126 public String getRegionName() { 127 return regionName; 128 } 129 130 public String getUserName() { 131 return userName; 132 } 133 134 public int getMultiGetsCount() { 135 return multiGetsCount; 136 } 137 138 public int getMultiMutationsCount() { 139 return multiMutationsCount; 140 } 141 142 public int getMultiServiceCalls() { 143 return multiServiceCalls; 144 } 145 146 /** 147 * If {@value org.apache.hadoop.hbase.HConstants#SLOW_LOG_SCAN_PAYLOAD_ENABLED} is enabled then 148 * this value may be present and should represent the Scan that produced the given 149 * {@link OnlineLogRecord} 150 */ 151 public Optional<Scan> getScan() { 152 return scan; 153 } 154 155 OnlineLogRecord(final long startTime, final int processingTime, final int queueTime, 156 final long responseSize, final long blockBytesScanned, final String clientAddress, 157 final String serverClass, final String methodName, final String callDetails, final String param, 158 final String regionName, final String userName, final int multiGetsCount, 159 final int multiMutationsCount, final int multiServiceCalls, final Scan scan) { 160 this.startTime = startTime; 161 this.processingTime = processingTime; 162 this.queueTime = queueTime; 163 this.responseSize = responseSize; 164 this.blockBytesScanned = blockBytesScanned; 165 this.clientAddress = clientAddress; 166 this.serverClass = serverClass; 167 this.methodName = methodName; 168 this.callDetails = callDetails; 169 this.param = param; 170 this.regionName = regionName; 171 this.userName = userName; 172 this.multiGetsCount = multiGetsCount; 173 this.multiMutationsCount = multiMutationsCount; 174 this.multiServiceCalls = multiServiceCalls; 175 this.scan = Optional.ofNullable(scan); 176 } 177 178 public static class OnlineLogRecordBuilder { 179 private long startTime; 180 private int processingTime; 181 private int queueTime; 182 private long responseSize; 183 private long blockBytesScanned; 184 private String clientAddress; 185 private String serverClass; 186 private String methodName; 187 private String callDetails; 188 private String param; 189 private String regionName; 190 private String userName; 191 private int multiGetsCount; 192 private int multiMutationsCount; 193 private int multiServiceCalls; 194 private Scan scan = null; 195 196 public OnlineLogRecordBuilder setStartTime(long startTime) { 197 this.startTime = startTime; 198 return this; 199 } 200 201 public OnlineLogRecordBuilder setProcessingTime(int processingTime) { 202 this.processingTime = processingTime; 203 return this; 204 } 205 206 public OnlineLogRecordBuilder setQueueTime(int queueTime) { 207 this.queueTime = queueTime; 208 return this; 209 } 210 211 public OnlineLogRecordBuilder setResponseSize(long responseSize) { 212 this.responseSize = responseSize; 213 return this; 214 } 215 216 /** 217 * Sets the amount of block bytes scanned to retrieve the response cells. 218 */ 219 public OnlineLogRecordBuilder setBlockBytesScanned(long blockBytesScanned) { 220 this.blockBytesScanned = blockBytesScanned; 221 return this; 222 } 223 224 public OnlineLogRecordBuilder setClientAddress(String clientAddress) { 225 this.clientAddress = clientAddress; 226 return this; 227 } 228 229 public OnlineLogRecordBuilder setServerClass(String serverClass) { 230 this.serverClass = serverClass; 231 return this; 232 } 233 234 public OnlineLogRecordBuilder setMethodName(String methodName) { 235 this.methodName = methodName; 236 return this; 237 } 238 239 public OnlineLogRecordBuilder setCallDetails(String callDetails) { 240 this.callDetails = callDetails; 241 return this; 242 } 243 244 public OnlineLogRecordBuilder setParam(String param) { 245 this.param = param; 246 return this; 247 } 248 249 public OnlineLogRecordBuilder setRegionName(String regionName) { 250 this.regionName = regionName; 251 return this; 252 } 253 254 public OnlineLogRecordBuilder setUserName(String userName) { 255 this.userName = userName; 256 return this; 257 } 258 259 public OnlineLogRecordBuilder setMultiGetsCount(int multiGetsCount) { 260 this.multiGetsCount = multiGetsCount; 261 return this; 262 } 263 264 public OnlineLogRecordBuilder setMultiMutationsCount(int multiMutationsCount) { 265 this.multiMutationsCount = multiMutationsCount; 266 return this; 267 } 268 269 public OnlineLogRecordBuilder setMultiServiceCalls(int multiServiceCalls) { 270 this.multiServiceCalls = multiServiceCalls; 271 return this; 272 } 273 274 public OnlineLogRecordBuilder setScan(Scan scan) { 275 this.scan = scan; 276 return this; 277 } 278 279 public OnlineLogRecord build() { 280 return new OnlineLogRecord(startTime, processingTime, queueTime, responseSize, 281 blockBytesScanned, clientAddress, serverClass, methodName, callDetails, param, regionName, 282 userName, multiGetsCount, multiMutationsCount, multiServiceCalls, scan); 283 } 284 } 285 286 @Override 287 public boolean equals(Object o) { 288 if (this == o) { 289 return true; 290 } 291 292 if (o == null || getClass() != o.getClass()) { 293 return false; 294 } 295 296 OnlineLogRecord that = (OnlineLogRecord) o; 297 298 return new EqualsBuilder().append(startTime, that.startTime) 299 .append(processingTime, that.processingTime).append(queueTime, that.queueTime) 300 .append(responseSize, that.responseSize).append(blockBytesScanned, that.blockBytesScanned) 301 .append(multiGetsCount, that.multiGetsCount) 302 .append(multiMutationsCount, that.multiMutationsCount) 303 .append(multiServiceCalls, that.multiServiceCalls).append(clientAddress, that.clientAddress) 304 .append(serverClass, that.serverClass).append(methodName, that.methodName) 305 .append(callDetails, that.callDetails).append(param, that.param) 306 .append(regionName, that.regionName).append(userName, that.userName).append(scan, that.scan) 307 .isEquals(); 308 } 309 310 @Override 311 public int hashCode() { 312 return new HashCodeBuilder(17, 37).append(startTime).append(processingTime).append(queueTime) 313 .append(responseSize).append(blockBytesScanned).append(clientAddress).append(serverClass) 314 .append(methodName).append(callDetails).append(param).append(regionName).append(userName) 315 .append(multiGetsCount).append(multiMutationsCount).append(multiServiceCalls).append(scan) 316 .toHashCode(); 317 } 318 319 @Override 320 public String toJsonPrettyPrint() { 321 return GSON.toJson(this); 322 } 323 324 @Override 325 public String toString() { 326 return new ToStringBuilder(this).append("startTime", startTime) 327 .append("processingTime", processingTime).append("queueTime", queueTime) 328 .append("responseSize", responseSize).append("blockBytesScanned", blockBytesScanned) 329 .append("clientAddress", clientAddress).append("serverClass", serverClass) 330 .append("methodName", methodName).append("callDetails", callDetails).append("param", param) 331 .append("regionName", regionName).append("userName", userName) 332 .append("multiGetsCount", multiGetsCount).append("multiMutationsCount", multiMutationsCount) 333 .append("multiServiceCalls", multiServiceCalls).append("scan", scan).toString(); 334 } 335 336}