View Javadoc

1   /*
2    * Copyright 2009 Red Hat, Inc.
3    *
4    * Red Hat licenses this file to you under the Apache License, version 2.0
5    * (the "License"); you may not use this file except in compliance with the
6    * License.  You may obtain a copy of the License at:
7    *
8    *    http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package org.jboss.netty.handler.logging;
17  
18  import static org.jboss.netty.buffer.ChannelBuffers.*;
19  
20  import org.jboss.netty.buffer.ChannelBuffer;
21  import org.jboss.netty.channel.ChannelDownstreamHandler;
22  import org.jboss.netty.channel.ChannelEvent;
23  import org.jboss.netty.channel.ChannelHandler;
24  import org.jboss.netty.channel.ChannelHandlerContext;
25  import org.jboss.netty.channel.ChannelUpstreamHandler;
26  import org.jboss.netty.channel.ExceptionEvent;
27  import org.jboss.netty.channel.MessageEvent;
28  import org.jboss.netty.channel.ChannelHandler.Sharable;
29  import org.jboss.netty.logging.InternalLogLevel;
30  import org.jboss.netty.logging.InternalLogger;
31  import org.jboss.netty.logging.InternalLoggerFactory;
32  
33  /**
34   * A {@link ChannelHandler} that logs all events via {@link InternalLogger}.
35   * By default, all events are logged at <tt>DEBUG</tt> level.  You can extend
36   * this class and override {@link #log(ChannelEvent)} to change the default
37   * behavior.
38   *
39   * @author <a href="http://www.jboss.org/netty/">The Netty Project</a>
40   * @author <a href="http://gleamynode.net/">Trustin Lee</a>
41   * @version $Rev: 2121 $, $Date: 2010-02-02 09:38:07 +0900 (Tue, 02 Feb 2010) $
42   *
43   * @apiviz.landmark
44   */
45  @Sharable
46  public class LoggingHandler implements ChannelUpstreamHandler, ChannelDownstreamHandler {
47  
48      private static final InternalLogLevel DEFAULT_LEVEL = InternalLogLevel.DEBUG;
49  
50      private final InternalLogger logger;
51      private final InternalLogLevel level;
52      private final boolean hexDump;
53  
54      /**
55       * Creates a new instance whose logger name is the fully qualified class
56       * name of the instance with hex dump enabled.
57       */
58      public LoggingHandler() {
59          this(true);
60      }
61  
62      /**
63       * Creates a new instance whose logger name is the fully qualified class
64       * name of the instance.
65       *
66       * @param level   the log level
67       */
68      public LoggingHandler(InternalLogLevel level) {
69          this(level, true);
70      }
71  
72      /**
73       * Creates a new instance whose logger name is the fully qualified class
74       * name of the instance.
75       *
76       * @param hexDump {@code true} if and only if the hex dump of the received
77       *                message is logged
78       */
79      public LoggingHandler(boolean hexDump) {
80          this(DEFAULT_LEVEL, hexDump);
81      }
82  
83      /**
84       * Creates a new instance whose logger name is the fully qualified class
85       * name of the instance.
86       *
87       * @param level   the log level
88       * @param hexDump {@code true} if and only if the hex dump of the received
89       *                message is logged
90       */
91      public LoggingHandler(InternalLogLevel level, boolean hexDump) {
92          if (level == null) {
93              throw new NullPointerException("level");
94          }
95  
96          logger = InternalLoggerFactory.getInstance(getClass());
97          this.level = level;
98          this.hexDump = hexDump;
99      }
100 
101     /**
102      * Creates a new instance with the specified logger name and with hex dump
103      * enabled.
104      */
105     public LoggingHandler(Class<?> clazz) {
106         this(clazz, true);
107     }
108 
109     /**
110      * Creates a new instance with the specified logger name.
111      *
112      * @param hexDump {@code true} if and only if the hex dump of the received
113      *                message is logged
114      */
115     public LoggingHandler(Class<?> clazz, boolean hexDump) {
116         this(clazz, DEFAULT_LEVEL, hexDump);
117     }
118 
119     /**
120      * Creates a new instance with the specified logger name.
121      *
122      * @param level   the log level
123      */
124     public LoggingHandler(Class<?> clazz, InternalLogLevel level) {
125         this(clazz, level, true);
126     }
127 
128     /**
129      * Creates a new instance with the specified logger name.
130      *
131      * @param level   the log level
132      * @param hexDump {@code true} if and only if the hex dump of the received
133      *                message is logged
134      */
135     public LoggingHandler(Class<?> clazz, InternalLogLevel level, boolean hexDump) {
136         if (clazz == null) {
137             throw new NullPointerException("clazz");
138         }
139         if (level == null) {
140             throw new NullPointerException("level");
141         }
142         logger = InternalLoggerFactory.getInstance(clazz);
143         this.level = level;
144         this.hexDump = hexDump;
145     }
146 
147     /**
148      * Creates a new instance with the specified logger name and with hex dump
149      * enabled.
150      */
151     public LoggingHandler(String name) {
152         this(name, true);
153     }
154 
155     /**
156      * Creates a new instance with the specified logger name.
157      *
158      * @param hexDump {@code true} if and only if the hex dump of the received
159      *                message is logged
160      */
161     public LoggingHandler(String name, boolean hexDump) {
162         this(name, DEFAULT_LEVEL, hexDump);
163     }
164 
165     /**
166      * Creates a new instance with the specified logger name.
167      *
168      * @param level   the log level
169      * @param hexDump {@code true} if and only if the hex dump of the received
170      *                message is logged
171      */
172     public LoggingHandler(String name, InternalLogLevel level, boolean hexDump) {
173         if (name == null) {
174             throw new NullPointerException("name");
175         }
176         if (level == null) {
177             throw new NullPointerException("level");
178         }
179         logger = InternalLoggerFactory.getInstance(name);
180         this.level = level;
181         this.hexDump = hexDump;
182     }
183 
184     /**
185      * Returns the {@link InternalLogger} that this handler uses to log
186      * a {@link ChannelEvent}.
187      */
188     public InternalLogger getLogger() {
189         return logger;
190     }
191 
192     /**
193      * Returns the {@link InternalLogLevel} that this handler uses to log
194      * a {@link ChannelEvent}.
195      */
196     public InternalLogLevel getLevel() {
197         return level;
198     }
199 
200     /**
201      * Logs the specified event to the {@link InternalLogger} returned by
202      * {@link #getLogger()}. If hex dump has been enabled for this handler,
203      * the hex dump of the {@link ChannelBuffer} in a {@link MessageEvent} will
204      * be logged together.
205      */
206     public void log(ChannelEvent e) {
207         if (getLogger().isEnabled(level)) {
208             String msg = e.toString();
209 
210             // Append hex dump if necessary.
211             if (hexDump && e instanceof MessageEvent) {
212                 MessageEvent me = (MessageEvent) e;
213                 if (me.getMessage() instanceof ChannelBuffer) {
214                     ChannelBuffer buf = (ChannelBuffer) me.getMessage();
215                     msg = msg + " - (HEXDUMP: " + hexDump(buf) + ')';
216                 }
217             }
218 
219             // Log the message (and exception if available.)
220             if (e instanceof ExceptionEvent) {
221                 getLogger().log(level, msg, ((ExceptionEvent) e).getCause());
222             } else {
223                 getLogger().log(level, msg);
224             }
225         }
226     }
227 
228     public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e)
229             throws Exception {
230         log(e);
231         ctx.sendUpstream(e);
232     }
233 
234     public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e)
235             throws Exception {
236         log(e);
237         ctx.sendDownstream(e);
238     }
239 }