说明
io.netty.handler.logging.LoggingHandler是一个channelhandler,利用日志框架记录事件日志。默认以DEBUG级别、数据以十六进制的形式记录日志。
LoggingHandler记录日志用的是底层的日志框架。例如,如果maven工程中有对log4j 2日志框架的依赖,那么会使用这个来记录日志。日志的格式就会调用log4j 2的配置,例如从maven工程src/main/resources/log4j2.xml读取配置。
示例
server端
maven工程的log4j2.xml
server端maven工程src/main/resources/log4j2.xml的内容:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
server端代码片段
package com.thb.power.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
/**
* Server端主类
* @author thb
*
*/
public class MainStation {
static final int PORT = Integer.parseInt(System.getProperty("port", "22335"));
public static void main(String[] args) throws Exception {
// 配置服务器
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 100)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new MainStationInitializer());
// 启动服务端
ChannelFuture f = b.bind(PORT).sync();
// 等待直到server socket关闭
f.channel().closeFuture().sync();
} finally {
// 关闭所有event loops以便终止所有的线程
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
// 定义的ChannelInitializer的子类
package com.thb.power.server;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
public class MainStationInitializer extends ChannelInitializer<SocketChannel> {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
p.addLast(new LoggingHandler(LogLevel.INFO));
}
}
启发服务端,查看输出日志
用maven的exec:java命令启动Server端:
mvn exec:java -Dexec.mainClass=com.thb.power.server.MainStation
输出:
从上面输出可以发现,在控制台输出了几个事件的日志:REGISTERED、BIND、ACTIVE。
Client端
maven工程的log4j2.xml
client端maven工程src/main/resources/log4j2.xml的内容:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
Client端代码片段
package com.thb.power.terminal;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import com.thb.power.packet.register.RegisterRequestPacket;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
/**
* Client端主类
* @author thb
*
*/
public class Terminal {
// 要连接的服务端的host
static final String HOST = System.getProperty("host", "127.0.0.1");
// 要连接的服务端的端口号
static final int PORT = Integer.parseInt(System.getProperty("port", "22335"));
public static void main(String[] args) throws Exception {
// 配置客户端
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new TerminalInitializer());
// 启动客户端
Channel ch = b.connect(HOST, PORT).sync().channel();
ChannelFuture lastWriteFuture = null;
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("please input(register):");
for (;;) {
String line = in.readLine();
if (line == null) {
break;
}
.......省略部分代码
if (lastWriteFuture != null) {
lastWriteFuture.sync();
}
} finally {
// 关闭event loop以便终止所有的线程
group.shutdownGracefully();
}
}
}
// 定义的ChannelInitializer的子类
package com.thb.power.terminal;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
public class TerminalInitializer extends ChannelInitializer<SocketChannel> {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
p.addLast(new LoggingHandler(LogLevel.INFO));
}
}
启动Client端,查看输出日志
用maven的exec:java命令启动Client端:
mvn exec:java -Dexec.mainClass=com.thb.power.terminal.Terminal
从上面输出可以发现,Client端启动后,跟服务端成功连接,打印了事件日志。
Client端和Server端交互,查看日志输出
在Client端输入业务命令后,日志中打印出了发送数据的十六进制形式:
再到服务端查看日志输出,读出了Client端发送的数据,也以十六进制的方式打印了日志。另外,还打印了READ、READ COMPLETE的事件日志: