美文网首页
【网络编程】Netty中的LoggingHandler好用到尖叫

【网络编程】Netty中的LoggingHandler好用到尖叫

作者: 程就人生 | 来源:发表于2023-03-15 20:42 被阅读0次

    前段时间使用 Netty 框架写 Demo,一直使用 org.slf4j jar 中的工具类,在测试编解码是否粘包/拆包的时候,一会儿在这里写一个 log.info,一会儿在那里写一个 log.error,不想要的时候还需要手动注释掉,真是太麻烦了。在 Netty 框架中,其实还有这么一个类 LoggingHandler,来帮助我们打印编解码中的进出信息,让我们先看下它的源码。

    1、LoggingHandler 源码分析

    LoggingHandler 继承自 ChannelDuplexHandler,ChannelDuplexHandler 继承了 ChannelInboundHandlerAdapter 类,实现了 ChannelOutboundHandler 接口,换句话说,LoggingHandler 既可以打印进站的数据,也可以打印出站的数据。

    在 LoggingHandler 类中,有一个注解 @Sharable ,说明在同一个 pipleline 中,它和其他 handler 是可以共享数据的。

    在 LoggingHandler 类中,有 6 个构造函数,3个成员变量。在 54 行的默认构造函数中,默认的日志打印级别是 DEBUG 级别。

    如果不想使用默认的日志级别,可以通过 64 行的构造函数单独设置。在这个构造函数中,logger 使用 Netty 中的内部日志工厂类 InternalLoggerFactory 通过getInstance 调用 getClass() 方法生成。

    日志级别,主要有 5 种类型,从打印日志的详细程度从多到少依次为:TRACE、DEBUG、INFO、WARN、ERROR。

    在 90 行的构造函数中,也可以通过传递过来的 Class 类来构造一个新的 logger 实例。

    LoggingHandler 重写了 channelRegistered 方法,也就是说当 ctx 发生注册行为的时候,这个方法会被调用,通过 isEnabled 判断是否可以打印,返回 true 时调用 log 方法并 format 格式化日志信息进行打印,不管是否打印日志,最后都会通过 ctx.fireChannelRegistered() 方法传递给下一个 handler。

    以此类推,LoggingHandler 日志打印处理器还重写了 channelUnregistered、channelActive、channelInactive、exceptionCaught、userEventTriggered、bind、connect、disconnect、close、deregister、channelReadComplete、channelRead、write、channelWritabilityChanged、flush 方法,打印日志的处理方式是一样的。

    日志打印的格式化方法有多种,其中 formatByteBuf 方法对接收到的 ByteBuf 类型数据进行格式化打印,formatByteBufHolder 方法对接收到的 ByteBufHolder 类型数据进行格式化打印,formatSimple 方法对其他类型的数据进行格式化打印。[图片上传失败...(image-d06ddd-1678970371091)]

    273 行的 format 方法只根据事件名称进行日志打印。


    306 行的 format 方法支持双对象的格式化日志输出,主要用于 connect 方法,打印本地 ip 地址和远程连接的客户端 ip 地址。[图片上传失败...(image-4624cc-1678970371091)]

    在 formatByteBuf 格式化方法中,使用 ByteBufUtil 工具类中的 appendPrettyHexDump 方法对打印格式进行了美化。
    2、LoggingHandler 简单使用

    就拿上次的 Websocket 编解码示例来看看 LoggingHandler 的使用。

    在编解码之前加入 LoggingHandler ,然后分别启动服务器端和客户端,并且点击客户端的 打开WebSocket 按钮,这时控制台会输出什么呢?

    image.png

    日志级别使用默认的 DEBUG 级别,WebSocket 请求的协议信息、服务器返回给客户端的协议信息,途中经过了哪几个事件,服务器端什么时候读的、写的,有没有 flush,一览无余。 我在浏览器发送信息,发送的是字符串信息,可是日志打印出来不太友好,怎么办?

    可以根据业务需求调整 LoggingHandler 在 pipeline 中的顺序,还可以给 LoggingHandler 传递要打印的对象的class,具体看业务逻辑。这里的 WebSocket 示例只是简单的demo,并没有将连接和处理分开,在这里就不再演示了。

    以上便是 LoggingHandler 简单使用,希望对你有帮助。

    相关文章

      网友评论

          本文标题:【网络编程】Netty中的LoggingHandler好用到尖叫

          本文链接:https://www.haomeiwen.com/subject/xmfrrdtx.html