@@ -185,6 +185,7 @@ protected Boolean channelReady() {
185
185
public void channelRead (ChannelHandlerContext ctx , Object msg ) throws Exception {
186
186
// Get a buffer that contains the full frame
187
187
ByteBuf buffer = (ByteBuf ) msg ;
188
+ requestStats .getNetworkTotalBytesIn ().add (buffer .readableBytes ());
188
189
189
190
// Update parse request latency metrics
190
191
final BiConsumer <Long , Throwable > registerRequestParseLatency = (timeBeforeParse , throwable ) -> {
@@ -405,7 +406,7 @@ protected void writeAndFlushResponseToClient(Channel channel) {
405
406
if (responseFuture .isCompletedExceptionally ()) {
406
407
responseFuture .exceptionally (e -> {
407
408
log .error ("[{}] request {} completed exceptionally" , channel , request .getHeader (), e );
408
- channel . writeAndFlush (request . createErrorResponse ( e ) );
409
+ sendErrorResponse (request , channel , e );
409
410
410
411
requestStats .getRequestStatsLogger (apiKey , KopServerStats .REQUEST_QUEUED_LATENCY )
411
412
.registerFailedEvent (nanoSecondsSinceCreated , TimeUnit .NANOSECONDS );
@@ -421,7 +422,7 @@ protected void writeAndFlushResponseToClient(Channel channel) {
421
422
// It should not be null, just check it for safety
422
423
log .error ("[{}] Unexpected null completed future for request {}" ,
423
424
ctx .channel (), request .getHeader ());
424
- channel . writeAndFlush (request . createErrorResponse ( new ApiException ("response is null" ) ));
425
+ sendErrorResponse (request , channel , new ApiException ("response is null" ));
425
426
return ;
426
427
}
427
428
if (log .isDebugEnabled ()) {
@@ -432,12 +433,15 @@ protected void writeAndFlushResponseToClient(Channel channel) {
432
433
}
433
434
434
435
final ByteBuf result = responseToByteBuf (response , request );
436
+ final int resultSize = result .readableBytes ();
435
437
channel .writeAndFlush (result ).addListener (future -> {
436
438
if (response instanceof ResponseCallbackWrapper ) {
437
439
((ResponseCallbackWrapper ) response ).responseComplete ();
438
440
}
439
441
if (!future .isSuccess ()) {
440
442
log .error ("[{}] Failed to write {}" , channel , request .getHeader (), future .cause ());
443
+ } else {
444
+ requestStats .getNetworkTotalBytesOut ().add (resultSize );
441
445
}
442
446
});
443
447
requestStats .getRequestStatsLogger (apiKey , KopServerStats .REQUEST_QUEUED_LATENCY )
@@ -451,14 +455,23 @@ protected void writeAndFlushResponseToClient(Channel channel) {
451
455
log .error ("[{}] request {} is not completed for {} ns (> {} ms)" ,
452
456
channel , request .getHeader (), nanoSecondsSinceCreated , kafkaConfig .getRequestTimeoutMs ());
453
457
responseFuture .cancel (true );
454
- channel .writeAndFlush (
455
- request .createErrorResponse (new ApiException ("request is expired from server side" )));
458
+ sendErrorResponse (request , channel , new ApiException ("request is expired from server side" ));
456
459
requestStats .getRequestStatsLogger (apiKey , KopServerStats .REQUEST_QUEUED_LATENCY )
457
460
.registerFailedEvent (nanoSecondsSinceCreated , TimeUnit .NANOSECONDS );
458
461
}
459
462
}
460
463
}
461
464
465
+ private void sendErrorResponse (KafkaHeaderAndRequest request , Channel channel , Throwable customError ) {
466
+ ByteBuf result = request .createErrorResponse (customError );
467
+ final int resultSize = result .readableBytes ();
468
+ channel .writeAndFlush (result ).addListener (future -> {
469
+ if (future .isSuccess ()) {
470
+ requestStats .getNetworkTotalBytesOut ().add (resultSize );
471
+ }
472
+ });
473
+ }
474
+
462
475
protected abstract boolean hasAuthenticated ();
463
476
464
477
protected abstract void channelPrepare (ChannelHandlerContext ctx ,
0 commit comments