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 }