We have a metered method legaced from ChannelInboundHandlerAdapter
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
...
//where we do our metering part here:
meterRegistry.timer(
"processing.handler.command.duration",
"command_name", commandName,
"success", Boolean.toString(true)
).record(duration, java.util.concurrent.TimeUnit.MILLISECONDS);
...
}
however, if there is an exception before this metering has happened, the
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
...
}
is thrown and we can't pass the same values we have initialized in channelRead
to put metrics on the same page with attributes channel
and duration
, but just mark them with homegrown attribute success=false
.
How to pass the values between channelRead
and exceptionCaught
?
It is possible to pass the attributes to the channel, String
or Integer
, they can be used for that.
Static initialization of the class:
private static final AttributeKey<Long> START_TIME_KEY = AttributeKey.valueOf("startTime");
private static final AttributeKey<String> COMMAND_NAME_KEY = AttributeKey.valueOf("commandName");
In channelRead()
:
ctx.channel().attr(START_TIME_KEY).set(System.currentTimeMillis());
String commandName = "unknown";
ctx.channel().attr(COMMAND_NAME_KEY).set(commandName);
In exceptionCaught()
:
long duration = System.currentTimeMillis() - ctx.channel().attr(START_TIME_KEY).get();
meterRegistry.timer(
"processing.handler.command.duration",
"command_name",ctx.channel().attr(COMMAND_NAME_KEY).get(),
"success", Boolean.toString(false)
).record(duration, java.util.concurrent.TimeUnit.MILLISECONDS);