Optimize LoggingHandler using lookup tables
This commit is contained in:
parent
c57d7dd098
commit
7a5f4721b9
@ -45,6 +45,64 @@ public class LoggingHandler extends ChannelHandlerAdapter<Object, Object> {
|
||||
private static final InternalLogLevel DEFAULT_LEVEL = InternalLogLevel.DEBUG;
|
||||
private static final String NEWLINE = String.format("%n");
|
||||
|
||||
private static final String[] BYTE2HEX = new String[256];
|
||||
private static final String[] HEXPADDING = new String[16];
|
||||
private static final String[] BYTEPADDING = new String[16];
|
||||
private static final char[] BYTE2CHAR = new char[256];
|
||||
|
||||
static {
|
||||
int i;
|
||||
|
||||
// Generate the lookup table for byte-to-hex-dump conversion
|
||||
for (i = 0; i < 10; i ++) {
|
||||
StringBuilder buf = new StringBuilder(3);
|
||||
buf.append(" 0");
|
||||
buf.append(i);
|
||||
BYTE2HEX[i] = buf.toString();
|
||||
}
|
||||
for (;i < 16; i ++) {
|
||||
StringBuilder buf = new StringBuilder(3);
|
||||
buf.append(" 0");
|
||||
buf.append((char) ('a' + i - 10));
|
||||
BYTE2HEX[i] = buf.toString();
|
||||
}
|
||||
for (; i < BYTE2HEX.length; i ++) {
|
||||
StringBuilder buf = new StringBuilder(3);
|
||||
buf.append(' ');
|
||||
buf.append(Integer.toHexString(i));
|
||||
BYTE2HEX[i] = buf.toString();
|
||||
}
|
||||
|
||||
// Generate the lookup table for hex dump paddings
|
||||
for (i = 0; i < HEXPADDING.length; i ++) {
|
||||
int padding = HEXPADDING.length - i;
|
||||
StringBuilder buf = new StringBuilder(padding * 3);
|
||||
for (int j = 0; j < padding; j ++) {
|
||||
buf.append(" ");
|
||||
}
|
||||
HEXPADDING[i] = buf.toString();
|
||||
}
|
||||
|
||||
// Generate the lookup table for byte dump paddings
|
||||
for (i = 0; i < BYTEPADDING.length; i ++) {
|
||||
int padding = BYTEPADDING.length - i;
|
||||
StringBuilder buf = new StringBuilder(padding);
|
||||
for (int j = 0; j < padding; j ++) {
|
||||
buf.append(' ');
|
||||
}
|
||||
BYTEPADDING[i] = buf.toString();
|
||||
}
|
||||
|
||||
// Generate the lookup table for byte-to-char conversion
|
||||
for (i = 0; i < BYTE2CHAR.length; i ++) {
|
||||
if (i <= 0x1f || i >= 0x7f) {
|
||||
BYTE2CHAR[i] = '.';
|
||||
} else {
|
||||
BYTE2CHAR[i] = (char) i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final InternalLogger logger;
|
||||
private final InternalLogLevel level;
|
||||
|
||||
@ -172,66 +230,65 @@ public class LoggingHandler extends ChannelHandlerAdapter<Object, Object> {
|
||||
elemType = "Object";
|
||||
}
|
||||
|
||||
return String.format("%s[%s](%d): %s", bufName, elemType, size, content);
|
||||
StringBuilder buf = new StringBuilder(bufName.length() + elemType.length() + content.length() + 16);
|
||||
buf.append(bufName);
|
||||
buf.append('[');
|
||||
buf.append(elemType);
|
||||
buf.append("](");
|
||||
buf.append(size);
|
||||
buf.append("): ");
|
||||
buf.append(content);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private static String hexdump(ChannelBuffer buf) {
|
||||
// TODO: Optimize using lookup tables
|
||||
int length = buf.readableBytes();
|
||||
int rows = length / 16 + (length % 15 == 0? 0 : 1) + 4;
|
||||
StringBuilder dump = new StringBuilder(rows * 80);
|
||||
|
||||
dump.append(NEWLINE);
|
||||
dump.append(" +-------------------------------------------------+");
|
||||
dump.append(NEWLINE);
|
||||
dump.append(" | 0 1 2 3 4 5 6 7 8 9 a b c d e f |");
|
||||
dump.append(NEWLINE);
|
||||
dump.append("+--------+-------------------------------------------------+----------------+");
|
||||
dump.append(
|
||||
NEWLINE + " +-------------------------------------------------+" +
|
||||
NEWLINE + " | 0 1 2 3 4 5 6 7 8 9 a b c d e f |" +
|
||||
NEWLINE + "+--------+-------------------------------------------------+----------------+");
|
||||
|
||||
final int startIndex = buf.readerIndex();
|
||||
final int endIndex = buf.writerIndex();
|
||||
|
||||
int i;
|
||||
for (i = buf.readerIndex(); i < buf.writerIndex(); i ++) {
|
||||
int relIdx = i - buf.readerIndex();
|
||||
for (i = startIndex; i < endIndex; i ++) {
|
||||
int relIdx = i - startIndex;
|
||||
int relIdxMod16 = relIdx & 15;
|
||||
if (relIdxMod16 == 0) {
|
||||
dump.append(NEWLINE);
|
||||
dump.append(String.format("|%8x|", relIdx));
|
||||
dump.append(Long.toHexString(relIdx & 0xFFFFFFFFL | 0x100000000L));
|
||||
dump.setCharAt(dump.length() - 9, '|');
|
||||
dump.append('|');
|
||||
}
|
||||
dump.append(String.format(" %02x", buf.getUnsignedByte(i)));
|
||||
dump.append(BYTE2HEX[buf.getUnsignedByte(i)]);
|
||||
if (relIdxMod16 == 15) {
|
||||
dump.append(" |");
|
||||
for (int j = i - 15; j <= i; j ++) {
|
||||
dump.append(toChar(buf.getByte(j)));
|
||||
dump.append(BYTE2CHAR[buf.getUnsignedByte(j)]);
|
||||
}
|
||||
dump.append('|');
|
||||
}
|
||||
}
|
||||
if ((i - buf.readerIndex() & 15) != 0) {
|
||||
|
||||
if ((i - startIndex & 15) != 0) {
|
||||
int remainder = length & 15;
|
||||
for (int j = 16 - remainder; j > 0; j --) {
|
||||
dump.append(" ");
|
||||
}
|
||||
dump.append(HEXPADDING[remainder]);
|
||||
dump.append(" |");
|
||||
for (int j = i - remainder; j < i; j ++) {
|
||||
dump.append(toChar(buf.getByte(j)));
|
||||
}
|
||||
for (int j = 16 - remainder; j > 0; j --) {
|
||||
dump.append(' ');
|
||||
dump.append(BYTE2CHAR[buf.getUnsignedByte(j)]);
|
||||
}
|
||||
dump.append(BYTEPADDING[remainder]);
|
||||
dump.append('|');
|
||||
}
|
||||
|
||||
dump.append(NEWLINE);
|
||||
dump.append("+--------+-------------------------------------------------+----------------+");
|
||||
return dump.toString();
|
||||
}
|
||||
dump.append(
|
||||
NEWLINE + "+--------+-------------------------------------------------+----------------+");
|
||||
|
||||
private static char toChar(int ch) {
|
||||
ch = ch & 0xff;
|
||||
if (ch <= 0x1f || ch >= 0x7f) {
|
||||
return '.';
|
||||
} else {
|
||||
return (char) ch;
|
||||
}
|
||||
return dump.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -286,7 +343,7 @@ public class LoggingHandler extends ChannelHandlerAdapter<Object, Object> {
|
||||
public void exceptionCaught(ChannelInboundHandlerContext<Object> ctx,
|
||||
Throwable cause) throws Exception {
|
||||
if (getLogger().isEnabled(level)) {
|
||||
logger.log(level, format(ctx, String.format("EXCEPTION: %s", cause)), cause);
|
||||
logger.log(level, format(ctx, "EXCEPTION: " + cause), cause);
|
||||
}
|
||||
super.exceptionCaught(ctx, cause);
|
||||
}
|
||||
@ -295,7 +352,7 @@ public class LoggingHandler extends ChannelHandlerAdapter<Object, Object> {
|
||||
public void userEventTriggered(ChannelInboundHandlerContext<Object> ctx,
|
||||
Object evt) throws Exception {
|
||||
if (getLogger().isEnabled(level)) {
|
||||
logger.log(level, format(ctx, String.format("USER_EVENT: %s", evt)));
|
||||
logger.log(level, format(ctx, "USER_EVENT: " + evt));
|
||||
}
|
||||
super.userEventTriggered(ctx, evt);
|
||||
}
|
||||
@ -313,7 +370,7 @@ public class LoggingHandler extends ChannelHandlerAdapter<Object, Object> {
|
||||
public void bind(ChannelOutboundHandlerContext<Object> ctx,
|
||||
SocketAddress localAddress, ChannelFuture future) throws Exception {
|
||||
if (getLogger().isEnabled(level)) {
|
||||
logger.log(level, format(ctx, String.format("BIND(%s)", localAddress)));
|
||||
logger.log(level, format(ctx, "BIND(" + localAddress + ')'));
|
||||
}
|
||||
super.bind(ctx, localAddress, future);
|
||||
}
|
||||
@ -323,7 +380,7 @@ public class LoggingHandler extends ChannelHandlerAdapter<Object, Object> {
|
||||
SocketAddress remoteAddress, SocketAddress localAddress,
|
||||
ChannelFuture future) throws Exception {
|
||||
if (getLogger().isEnabled(level)) {
|
||||
logger.log(level, format(ctx, String.format("CONNECT(%s, %s)", remoteAddress, localAddress)));
|
||||
logger.log(level, format(ctx, "CONNECT(" + remoteAddress + ", " + localAddress + ')'));
|
||||
}
|
||||
super.connect(ctx, remoteAddress, localAddress, future);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user