1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.http2;
17
18 import static io.netty.util.internal.ObjectUtil.checkNotNull;
19 import io.netty.buffer.ByteBuf;
20 import io.netty.buffer.ByteBufUtil;
21 import io.netty.channel.ChannelHandlerAdapter;
22 import io.netty.util.internal.logging.InternalLogLevel;
23 import io.netty.util.internal.logging.InternalLogger;
24 import io.netty.util.internal.logging.InternalLoggerFactory;
25
26
27
28
29 public class Http2FrameLogger extends ChannelHandlerAdapter {
30
31 public enum Direction {
32 INBOUND,
33 OUTBOUND
34 }
35
36 private final InternalLogger logger;
37 private final InternalLogLevel level;
38
39 public Http2FrameLogger(InternalLogLevel level) {
40 this(level, InternalLoggerFactory.getInstance(Http2FrameLogger.class));
41 }
42
43 public Http2FrameLogger(InternalLogLevel level, InternalLogger logger) {
44 this.level = checkNotNull(level, "level");
45 this.logger = checkNotNull(logger, "logger");
46 }
47
48 public void logData(Direction direction, int streamId, ByteBuf data, int padding,
49 boolean endStream) {
50 log(direction,
51 "DATA: streamId=%d, padding=%d, endStream=%b, length=%d, bytes=%s",
52 streamId, padding, endStream, data.readableBytes(), ByteBufUtil.hexDump(data));
53 }
54
55 public void logHeaders(Direction direction, int streamId, Http2Headers headers, int padding,
56 boolean endStream) {
57 log(direction, "HEADERS: streamId:%d, headers=%s, padding=%d, endStream=%b",
58 streamId, headers, padding, endStream);
59 }
60
61 public void logHeaders(Direction direction, int streamId, Http2Headers headers,
62 int streamDependency, short weight, boolean exclusive, int padding, boolean endStream) {
63 log(direction,
64 "HEADERS: streamId:%d, headers=%s, streamDependency=%d, weight=%d, exclusive=%b, "
65 + "padding=%d, endStream=%b", streamId, headers,
66 streamDependency, weight, exclusive, padding, endStream);
67 }
68
69 public void logPriority(Direction direction, int streamId, int streamDependency, short weight,
70 boolean exclusive) {
71 log(direction, "PRIORITY: streamId=%d, streamDependency=%d, weight=%d, exclusive=%b",
72 streamId, streamDependency, weight, exclusive);
73 }
74
75 public void logRstStream(Direction direction, int streamId, long errorCode) {
76 log(direction, "RST_STREAM: streamId=%d, errorCode=%d", streamId, errorCode);
77 }
78
79 public void logSettingsAck(Direction direction) {
80 log(direction, "SETTINGS ack=true");
81 }
82
83 public void logSettings(Direction direction, Http2Settings settings) {
84 log(direction, "SETTINGS: ack=false, settings=%s", settings);
85 }
86
87 public void logPing(Direction direction, ByteBuf data) {
88 log(direction, "PING: ack=false, length=%d, bytes=%s", data.readableBytes(), ByteBufUtil.hexDump(data));
89 }
90
91 public void logPingAck(Direction direction, ByteBuf data) {
92 log(direction, "PING: ack=true, length=%d, bytes=%s", data.readableBytes(), ByteBufUtil.hexDump(data));
93 }
94
95 public void logPushPromise(Direction direction, int streamId, int promisedStreamId,
96 Http2Headers headers, int padding) {
97 log(direction, "PUSH_PROMISE: streamId=%d, promisedStreamId=%d, headers=%s, padding=%d",
98 streamId, promisedStreamId, headers, padding);
99 }
100
101 public void logGoAway(Direction direction, int lastStreamId, long errorCode, ByteBuf debugData) {
102 log(direction, "GO_AWAY: lastStreamId=%d, errorCode=%d, length=%d, bytes=%s", lastStreamId,
103 errorCode, debugData.readableBytes(), ByteBufUtil.hexDump(debugData));
104 }
105
106 public void logWindowsUpdate(Direction direction, int streamId, int windowSizeIncrement) {
107 log(direction, "WINDOW_UPDATE: streamId=%d, windowSizeIncrement=%d", streamId,
108 windowSizeIncrement);
109 }
110
111 public void logUnknownFrame(Direction direction, byte frameType, int streamId, Http2Flags flags, ByteBuf data) {
112 log(direction, "UNKNOWN: frameType=%d, streamId=%d, flags=%d, length=%d, bytes=%s",
113 frameType & 0xFF, streamId, flags.value(), data.readableBytes(), ByteBufUtil.hexDump(data));
114 }
115
116 private void log(Direction direction, String format, Object... args) {
117 if (logger.isEnabled(level)) {
118 StringBuilder b = new StringBuilder(200);
119 b.append("\n----------------")
120 .append(direction.name())
121 .append("--------------------\n")
122 .append(String.format(format, args))
123 .append("\n------------------------------------");
124 logger.log(level, b.toString());
125 }
126 }
127 }