@@ -3316,7 +3316,8 @@ private void checkLimitOfRows(int numOfCompleteRows, int limitOfRows, boolean mo
33163316 // return whether we have more results in region.
33173317 private void scan (HBaseRpcController controller , ScanRequest request , RegionScannerHolder rsh ,
33183318 long maxQuotaResultSize , int maxResults , int limitOfRows , List <Result > results ,
3319- ScanResponse .Builder builder , RpcCall rpcCall ) throws IOException {
3319+ ScanResponse .Builder builder , RpcCall rpcCall , ServerSideScanMetrics scanMetrics )
3320+ throws IOException {
33203321 HRegion region = rsh .r ;
33213322 RegionScanner scanner = rsh .s ;
33223323 long maxResultSize ;
@@ -3369,8 +3370,6 @@ private void scan(HBaseRpcController controller, ScanRequest request, RegionScan
33693370 final LimitScope timeScope =
33703371 allowHeartbeatMessages ? LimitScope .BETWEEN_CELLS : LimitScope .BETWEEN_ROWS ;
33713372
3372- boolean trackMetrics = request .hasTrackScanMetrics () && request .getTrackScanMetrics ();
3373-
33743373 // Configure with limits for this RPC. Set keep progress true since size progress
33753374 // towards size limit should be kept between calls to nextRaw
33763375 ScannerContext .Builder contextBuilder = ScannerContext .newBuilder (true );
@@ -3392,7 +3391,8 @@ private void scan(HBaseRpcController controller, ScanRequest request, RegionScan
33923391 contextBuilder .setSizeLimit (sizeScope , maxCellSize , maxCellSize , maxBlockSize );
33933392 contextBuilder .setBatchLimit (scanner .getBatch ());
33943393 contextBuilder .setTimeLimit (timeScope , timeLimit );
3395- contextBuilder .setTrackMetrics (trackMetrics );
3394+ contextBuilder .setTrackMetrics (scanMetrics != null );
3395+ contextBuilder .setScanMetrics (scanMetrics );
33963396 ScannerContext scannerContext = contextBuilder .build ();
33973397 boolean limitReached = false ;
33983398 long blockBytesScannedBefore = 0 ;
@@ -3514,27 +3514,15 @@ private void scan(HBaseRpcController controller, ScanRequest request, RegionScan
35143514 builder .setMoreResultsInRegion (moreRows );
35153515 // Check to see if the client requested that we track metrics server side. If the
35163516 // client requested metrics, retrieve the metrics from the scanner context.
3517- if (trackMetrics ) {
3517+ if (scanMetrics != null ) {
35183518 // rather than increment yet another counter in StoreScanner, just set the value here
35193519 // from block size progress before writing into the response
3520- scannerContext .getMetrics ().setCounter (
3521- ServerSideScanMetrics .BLOCK_BYTES_SCANNED_KEY_METRIC_NAME ,
3520+ scanMetrics .setCounter (ServerSideScanMetrics .BLOCK_BYTES_SCANNED_KEY_METRIC_NAME ,
35223521 scannerContext .getBlockSizeProgress ());
35233522 if (rpcCall != null ) {
3524- scannerContext . getMetrics () .setCounter (ServerSideScanMetrics .FS_READ_TIME_METRIC_NAME ,
3523+ scanMetrics .setCounter (ServerSideScanMetrics .FS_READ_TIME_METRIC_NAME ,
35253524 rpcCall .getFsReadTime ());
35263525 }
3527- Map <String , Long > metrics = scannerContext .getMetrics ().getMetricsMap ();
3528- ScanMetrics .Builder metricBuilder = ScanMetrics .newBuilder ();
3529- NameInt64Pair .Builder pairBuilder = NameInt64Pair .newBuilder ();
3530-
3531- for (Entry <String , Long > entry : metrics .entrySet ()) {
3532- pairBuilder .setName (entry .getKey ());
3533- pairBuilder .setValue (entry .getValue ());
3534- metricBuilder .addMetrics (pairBuilder .build ());
3535- }
3536-
3537- builder .setScanMetrics (metricBuilder .build ());
35383526 }
35393527 }
35403528 } finally {
@@ -3671,6 +3659,8 @@ public ScanResponse scan(final RpcController controller, final ScanRequest reque
36713659 boolean scannerClosed = false ;
36723660 try {
36733661 List <Result > results = new ArrayList <>(Math .min (rows , 512 ));
3662+ boolean trackMetrics = request .hasTrackScanMetrics () && request .getTrackScanMetrics ();
3663+ ServerSideScanMetrics scanMetrics = trackMetrics ? new ServerSideScanMetrics () : null ;
36743664 if (rows > 0 ) {
36753665 boolean done = false ;
36763666 // Call coprocessor. Get region info from scanner.
@@ -3690,7 +3680,7 @@ public ScanResponse scan(final RpcController controller, final ScanRequest reque
36903680 }
36913681 if (!done ) {
36923682 scan ((HBaseRpcController ) controller , request , rsh , maxQuotaResultSize , rows , limitOfRows ,
3693- results , builder , rpcCall );
3683+ results , builder , rpcCall , scanMetrics );
36943684 } else {
36953685 builder .setMoreResultsInRegion (!results .isEmpty ());
36963686 }
@@ -3742,6 +3732,28 @@ public ScanResponse scan(final RpcController controller, final ScanRequest reque
37423732 throw new TimeoutIOException ("Client deadline exceeded, cannot return results" );
37433733 }
37443734
3735+ if (scanMetrics != null ) {
3736+ if (rpcCall != null ) {
3737+ long rpcScanTime = EnvironmentEdgeManager .currentTime () - rpcCall .getStartTime ();
3738+ long rpcQueueWaitTime = rpcCall .getStartTime () - rpcCall .getReceiveTime ();
3739+ scanMetrics .addToCounter (ServerSideScanMetrics .RPC_SCAN_PROCESSING_TIME_METRIC_NAME ,
3740+ rpcScanTime );
3741+ scanMetrics .addToCounter (ServerSideScanMetrics .RPC_SCAN_QUEUE_WAIT_TIME_METRIC_NAME ,
3742+ rpcQueueWaitTime );
3743+ }
3744+ Map <String , Long > metrics = scanMetrics .getMetricsMap ();
3745+ ScanMetrics .Builder metricBuilder = ScanMetrics .newBuilder ();
3746+ NameInt64Pair .Builder pairBuilder = NameInt64Pair .newBuilder ();
3747+
3748+ for (Entry <String , Long > entry : metrics .entrySet ()) {
3749+ pairBuilder .setName (entry .getKey ());
3750+ pairBuilder .setValue (entry .getValue ());
3751+ metricBuilder .addMetrics (pairBuilder .build ());
3752+ }
3753+
3754+ builder .setScanMetrics (metricBuilder .build ());
3755+ }
3756+
37453757 return builder .build ();
37463758 } catch (IOException e ) {
37473759 try {
0 commit comments