void logResponse(Message param, String methodName, String call, boolean tooLarge, boolean tooSlow,
    String clientAddress, long startTime, int processingTime, int qTime, long responseSize,
    long blockBytesScanned, long fsReadTime, String userName) {
    final String className = server == null ? StringUtils.EMPTY : server.getClass().getSimpleName();
    // base information that is reported regardless of type of call
    Map<String, Object> responseInfo = new HashMap<>();
    responseInfo.put("starttimems", startTime);
    responseInfo.put("processingtimems", processingTime);
    responseInfo.put("queuetimems", qTime);
    responseInfo.put("responsesize", responseSize);
    responseInfo.put("blockbytesscanned", blockBytesScanned);
    responseInfo.put("fsreadtime", fsReadTime);
    responseInfo.put("client", clientAddress);
    responseInfo.put("class", className);
    responseInfo.put("method", methodName);
    responseInfo.put("call", call);
    // The params could be really big, make sure they don't kill us at WARN
    String stringifiedParam = ProtobufUtil.getShortTextFormat(param);
    if (stringifiedParam.length() > 150) {
      // Truncate to 1000 chars if TRACE is on, else to 150 chars
      stringifiedParam = truncateTraceLog(stringifiedParam);
    }
    responseInfo.put("param", stringifiedParam);
    if (param instanceof ClientProtos.ScanRequest && rsRpcServices != null) {
      ClientProtos.ScanRequest request = ((ClientProtos.ScanRequest) param);
      String scanDetails;
      if (request.hasScannerId()) {
        long scannerId = request.getScannerId();
        scanDetails = rsRpcServices.getScanDetailsWithId(scannerId);
      } else {
        scanDetails = rsRpcServices.getScanDetailsWithRequest(request);
      }
      if (scanDetails != null) {
        responseInfo.put("scandetails", scanDetails);
      }
    }
    if (param instanceof ClientProtos.MultiRequest) {
      int numGets = 0;
      int numMutations = 0;
      int numServiceCalls = 0;
      ClientProtos.MultiRequest multi = (ClientProtos.MultiRequest) param;
      for (ClientProtos.RegionAction regionAction : multi.getRegionActionList()) {
        for (ClientProtos.Action action : regionAction.getActionList()) {
          if (action.hasMutation()) {
            numMutations++;
          }
          if (action.hasGet()) {
            numGets++;
          }
          if (action.hasServiceCall()) {
            numServiceCalls++;
          }
        }
      }
      responseInfo.put(MULTI_GETS, numGets);
      responseInfo.put(MULTI_MUTATIONS, numMutations);
      responseInfo.put(MULTI_SERVICE_CALLS, numServiceCalls);
    }
    final String tag =
      (tooLarge && tooSlow) ? "TooLarge & TooSlow" : (tooSlow ? "TooSlow" : "TooLarge");
    LOG.warn("(response" + tag + "): " + GSON.toJson(responseInfo));
  }
Logs an RPC response to the LOG file, producing valid JSON objects for client Operations.
@param param             The parameters received in the call.
@param methodName        The name of the method invoked
@param call              The string representation of the call
@param tooLarge          To indicate if the event is tooLarge
@param tooSlow           To indicate if the event is tooSlow
@param clientAddress     The address of the client who made this call.
@param startTime         The time that the call was initiated, in ms.
@param processingTime    The duration that the call took to run, in ms.
@param qTime             The duration that the call spent on the queue prior to being
                         initiated, in ms.
@param responseSize      The size in bytes of the response buffer.
@param blockBytesScanned The size of block bytes scanned to retrieve the response.
@param userName          UserName of the current RPC Call
hbase-server/src/main/java/org/apache/hadoop/hbase/ipc/RpcServer.java