博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Netty源码解析6-ChannelHandler实例之LoggingHandler
阅读量:6939 次
发布时间:2019-06-27

本文共 2656 字,大约阅读时间需要 8 分钟。

请戳GitHub原文:

更多文章关注:多线程/集合/分布式/Netty/NIO/RPC

LoggingHandler

日志处理器LoggingHandler是使用Netty进行开发时的好帮手,它可以对入站\出站事件进行日志记录,从而方便我们进行问题排查。首先看类签名:

@Sharable    public class LoggingHandler extends ChannelDuplexHandler复制代码

注解Sharable说明LoggingHandler没有状态相关变量,所有Channel可以使用一个实例。继承自ChannelDuplexHandler表示对入站出站事件都进行日志记录。最佳实践:使用static修饰LoggingHandler实例,并在生产环境删除LoggingHandler。 该类的成员变量如下:

// 实际使用的日志处理,slf4j、log4j等    protected final InternalLogger logger;    // 日志框架使用的日志级别    protected final InternalLogLevel internalLevel;    // Netty使用的日志级别    private final LogLevel level;        // 默认级别为Debug    private static final LogLevel DEFAULT_LEVEL = LogLevel.DEBUG;复制代码

看完成员变量,在移目构造方法,LoggingHandler的构造方法较多,一个典型的如下:

public LoggingHandler(LogLevel level) {        if (level == null) {            throw new NullPointerException("level");        }        // 获得实际的日志框架        logger = InternalLoggerFactory.getInstance(getClass());        // 设置日志级别        this.level = level;        internalLevel = level.toInternalLevel();    }复制代码

在构造方法中获取用户实际使用的日志框架,如slf4j、log4j等,并日志设置记录级别。其他的构造方法也类似,不在赘述。 记录出站、入站事件的过程类似,我们以ChannelRead()为例分析,代码如下:

public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {        logMessage(ctx, "RECEIVED", msg);   // 记录日志        ctx.fireChannelRead(msg);   // 传播事件    }        private void logMessage(ChannelHandlerContext ctx, String eventName, Object msg) {        if (logger.isEnabled(internalLevel)) {            logger.log(internalLevel, format(ctx, formatMessage(eventName, msg)));        }    }        protected String formatMessage(String eventName, Object msg) {        if (msg instanceof ByteBuf) {            return formatByteBuf(eventName, (ByteBuf) msg);        } else if (msg instanceof ByteBufHolder) {            return formatByteBufHolder(eventName, (ByteBufHolder) msg);        } else {            return formatNonByteBuf(eventName, msg);        }    }复制代码

其中的代码都简单明了,主要分析formatByteBuf()方法:

protected String formatByteBuf(String eventName, ByteBuf msg) {        int length = msg.readableBytes();        if (length == 0) {            StringBuilder buf = new StringBuilder(eventName.length() + 4);            buf.append(eventName).append(": 0B");            return buf.toString();        } else {            int rows = length / 16 + (length % 15 == 0? 0 : 1) + 4;            StringBuilder buf = new StringBuilder(eventName.length() +                         2 + 10 + 1 + 2 + rows * 80);            buf.append(eventName)                      .append(": ").append(length).append('B').append(NEWLINE);            appendPrettyHexDump(buf, msg);            return buf.toString();        }复制代码

其中的数字计算,容易让人失去耐心,使用逆向思维,放上结果反推:

转载地址:http://mwsnl.baihongyu.com/

你可能感兴趣的文章
Oracle数据库—— 存储过程与函数的创建
查看>>
由于行255而未能重新格式化文档。已还原为原始格式。
查看>>
MVC的view页面内嵌C#语法发现路径被转码的解决方法
查看>>
PMBOK项目管理PMI主义\IPMA概述
查看>>
vscode中使用node服务调试,会在promise的reject出现断点报错
查看>>
SilverLight之向后台请求数据-WebClient
查看>>
2008server安装Intel I217V网卡驱动
查看>>
安卓应用获取权限判断
查看>>
hdu 1695(欧拉函数 容斥定理)
查看>>
CentOS 6.7安装MySQL
查看>>
Docker容器互联
查看>>
Linux基础知识--文件操作
查看>>
java+jsp+mysql网页制作总结(3)
查看>>
DAY6-小变化(java提示框)-2018-1-16
查看>>
mysql在表的某一位置增加一列、删除一列、修改列名
查看>>
iOS 网络与多线程--3.异步Get方式的网络请求(非阻塞)
查看>>
Excel相同内容如何设置相同的背景色
查看>>
LCA问题
查看>>
计算机基础知识
查看>>
论文学习及报告总结
查看>>