private ClusterStatusProtos.ServerLoad buildServerLoad(long reportStartTime, long reportEndTime)
    throws IOException {
    // We're getting the MetricsRegionServerWrapper here because the wrapper computes requests
    // per second, and other metrics As long as metrics are part of ServerLoad it's best to use
    // the wrapper to compute those numbers in one place.
    // In the long term most of these should be moved off of ServerLoad and the heart beat.
    // Instead they should be stored in an HBase table so that external visibility into HBase is
    // improved; Additionally the load balancer will be able to take advantage of a more complete
    // history.
    MetricsRegionServerWrapper regionServerWrapper = metricsRegionServer.getRegionServerWrapper();
    Collection<HRegion> regions = getOnlineRegionsLocalContext();
    long usedMemory = -1L;
    long maxMemory = -1L;
    final MemoryUsage usage = MemorySizeUtil.safeGetHeapMemoryUsage();
    if (usage != null) {
      usedMemory = usage.getUsed();
      maxMemory = usage.getMax();
    }

    ClusterStatusProtos.ServerLoad.Builder serverLoad = ClusterStatusProtos.ServerLoad.newBuilder();
    serverLoad.setNumberOfRequests((int) regionServerWrapper.getRequestsPerSecond());
    serverLoad.setTotalNumberOfRequests(regionServerWrapper.getTotalRequestCount());
    serverLoad.setUsedHeapMB((int) (usedMemory / 1024 / 1024));
    serverLoad.setMaxHeapMB((int) (maxMemory / 1024 / 1024));
    serverLoad.setReadRequestsCount(this.metricsRegionServerImpl.getReadRequestsCount());
    serverLoad.setWriteRequestsCount(this.metricsRegionServerImpl.getWriteRequestsCount());
    Set<String> coprocessors = getWAL(null).getCoprocessorHost().getCoprocessors();
    Coprocessor.Builder coprocessorBuilder = Coprocessor.newBuilder();
    for (String coprocessor : coprocessors) {
      serverLoad.addCoprocessors(coprocessorBuilder.setName(coprocessor).build());
    }
    RegionLoad.Builder regionLoadBldr = RegionLoad.newBuilder();
    RegionSpecifier.Builder regionSpecifier = RegionSpecifier.newBuilder();
    for (HRegion region : regions) {
      if (region.getCoprocessorHost() != null) {
        Set<String> regionCoprocessors = region.getCoprocessorHost().getCoprocessors();
        for (String regionCoprocessor : regionCoprocessors) {
          serverLoad.addCoprocessors(coprocessorBuilder.setName(regionCoprocessor).build());
        }
      }
      serverLoad.addRegionLoads(createRegionLoad(region, regionLoadBldr, regionSpecifier));
      for (String coprocessor : getWAL(region.getRegionInfo()).getCoprocessorHost()
        .getCoprocessors()) {
        serverLoad.addCoprocessors(coprocessorBuilder.setName(coprocessor).build());
      }
    }

    getBlockCache().ifPresent(cache -> {
      cache.getRegionCachedInfo().ifPresent(regionCachedInfo -> {
        regionCachedInfo.forEach((regionName, prefetchSize) -> {
          serverLoad.putRegionCachedInfo(regionName, roundSize(prefetchSize, unitMB));
        });
      });
    });

    serverLoad.setReportStartTime(reportStartTime);
    serverLoad.setReportEndTime(reportEndTime);
    if (this.infoServer != null) {
      serverLoad.setInfoServerPort(this.infoServer.getPort());
    } else {
      serverLoad.setInfoServerPort(-1);
    }
    MetricsUserAggregateSource userSource =
      metricsRegionServer.getMetricsUserAggregate().getSource();
    if (userSource != null) {
      Map<String, MetricsUserSource> userMetricMap = userSource.getUserSources();
      for (Entry<String, MetricsUserSource> entry : userMetricMap.entrySet()) {
        serverLoad.addUserLoads(createUserLoad(entry.getKey(), entry.getValue()));
      }
    }

    if (sameReplicationSourceAndSink && replicationSourceHandler != null) {
      // always refresh first to get the latest value
      ReplicationLoad rLoad = replicationSourceHandler.refreshAndGetReplicationLoad();
      if (rLoad != null) {
        serverLoad.setReplLoadSink(rLoad.getReplicationLoadSink());
        for (ClusterStatusProtos.ReplicationLoadSource rLS : rLoad
          .getReplicationLoadSourceEntries()) {
          serverLoad.addReplLoadSource(rLS);
        }
      }
    } else {
      if (replicationSourceHandler != null) {
        ReplicationLoad rLoad = replicationSourceHandler.refreshAndGetReplicationLoad();
        if (rLoad != null) {
          for (ClusterStatusProtos.ReplicationLoadSource rLS : rLoad
            .getReplicationLoadSourceEntries()) {
            serverLoad.addReplLoadSource(rLS);
          }
        }
      }
      if (replicationSinkHandler != null) {
        ReplicationLoad rLoad = replicationSinkHandler.refreshAndGetReplicationLoad();
        if (rLoad != null) {
          serverLoad.setReplLoadSink(rLoad.getReplicationLoadSink());
        }
      }
    }

    TaskMonitor.get().getTasks().forEach(task -> serverLoad.addTasks(ClusterStatusProtos.ServerTask
      .newBuilder().setDescription(task.getDescription())
      .setStatus(task.getStatus() != null ? task.getStatus() : "")
      .setState(ClusterStatusProtos.ServerTask.State.valueOf(task.getState().name()))
      .setStartTime(task.getStartTime()).setCompletionTime(task.getCompletionTimestamp()).build()));

    return serverLoad.build();
  }
Converts a pair of {@link RegionInfo} and {@code long} into a {@link RegionSpaceUse} protobuf
message.
@param regionInfo  The RegionInfo
@param sizeInBytes The size in bytes of the Region
@return The protocol buffer
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java