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.Map; 021import org.apache.commons.lang3.builder.ToStringBuilder; 022import org.apache.hadoop.hbase.ipc.RpcCall; 023import org.apache.yetus.audience.InterfaceAudience; 024import org.slf4j.Logger; 025import org.slf4j.LoggerFactory; 026 027import org.apache.hbase.thirdparty.com.google.protobuf.InvalidProtocolBufferException; 028import org.apache.hbase.thirdparty.com.google.protobuf.Message; 029 030/** 031 * RpcCall details that would be passed on to ring buffer of slow log responses 032 */ 033@InterfaceAudience.Private 034public class RpcLogDetails extends NamedQueuePayload { 035 036 public static final int SLOW_LOG_EVENT = 0; 037 038 private static final Logger LOG = LoggerFactory.getLogger(RpcLogDetails.class.getName()); 039 040 private final RpcCall rpcCall; 041 private Message param; 042 private final String clientAddress; 043 private final long responseSize; 044 private final long blockBytesScanned; 045 private final long fsReadTime; 046 private final String className; 047 private final boolean isSlowLog; 048 private final boolean isLargeLog; 049 private final Map<String, byte[]> connectionAttributes; 050 private final Map<String, byte[]> requestAttributes; 051 052 public RpcLogDetails(RpcCall rpcCall, Message param, String clientAddress, long responseSize, 053 long blockBytesScanned, long fsReadTime, String className, boolean isSlowLog, 054 boolean isLargeLog) { 055 super(SLOW_LOG_EVENT); 056 this.rpcCall = rpcCall; 057 this.clientAddress = clientAddress; 058 this.responseSize = responseSize; 059 this.blockBytesScanned = blockBytesScanned; 060 this.fsReadTime = fsReadTime; 061 this.className = className; 062 this.isSlowLog = isSlowLog; 063 this.isLargeLog = isLargeLog; 064 065 // it's important to call getConnectionAttributes and getRequestAttributes here 066 // because otherwise the buffers may get released before the log details are processed which 067 // would result in corrupted attributes 068 this.connectionAttributes = rpcCall.getConnectionAttributes(); 069 this.requestAttributes = rpcCall.getRequestAttributes(); 070 071 // We also need to deep copy the message because the CodedInputStream may be 072 // overwritten before this slow log is consumed. Such overwriting could 073 // cause the slow log payload to be corrupt 074 try { 075 this.param = param.newBuilderForType().mergeFrom(param.toByteArray()).build(); 076 } catch (InvalidProtocolBufferException e) { 077 LOG.error("Failed to parse protobuf for message {}", param, e); 078 this.param = param; 079 } 080 } 081 082 public RpcCall getRpcCall() { 083 return rpcCall; 084 } 085 086 public String getClientAddress() { 087 return clientAddress; 088 } 089 090 public long getResponseSize() { 091 return responseSize; 092 } 093 094 public long getBlockBytesScanned() { 095 return blockBytesScanned; 096 } 097 098 public long getFsReadTime() { 099 return fsReadTime; 100 } 101 102 public String getClassName() { 103 return className; 104 } 105 106 public boolean isSlowLog() { 107 return isSlowLog; 108 } 109 110 public boolean isLargeLog() { 111 return isLargeLog; 112 } 113 114 public Message getParam() { 115 return param; 116 } 117 118 public Map<String, byte[]> getConnectionAttributes() { 119 return connectionAttributes; 120 } 121 122 public Map<String, byte[]> getRequestAttributes() { 123 return requestAttributes; 124 } 125 126 @Override 127 public String toString() { 128 return new ToStringBuilder(this).append("rpcCall", rpcCall).append("param", param) 129 .append("clientAddress", clientAddress).append("responseSize", responseSize) 130 .append("className", className).append("isSlowLog", isSlowLog) 131 .append("isLargeLog", isLargeLog).append("connectionAttributes", connectionAttributes) 132 .append("requestAttributes", requestAttributes).toString(); 133 } 134}