001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 *
019 */
020package org.apache.mina.filter.logging;
021
022import org.apache.mina.core.filterchain.IoFilter;
023import org.apache.mina.core.filterchain.IoFilterAdapter;
024import org.apache.mina.core.session.IdleStatus;
025import org.apache.mina.core.session.IoEventType;
026import org.apache.mina.core.session.IoSession;
027import org.apache.mina.core.write.WriteRequest;
028import org.slf4j.Logger;
029import org.slf4j.LoggerFactory;
030
031/**
032 * Logs all MINA protocol events.  Each event can be
033 * tuned to use a different level based on the user's specific requirements.  Methods
034 * are in place that allow the user to use either the get or set method for each event
035 * and pass in the {@link IoEventType} and the {@link LogLevel}.
036 *
037 * By default, all events are logged to the {@link LogLevel#INFO} level except
038 * {@link IoFilterAdapter#exceptionCaught(IoFilter.NextFilter, IoSession, Throwable)},
039 * which is logged to {@link LogLevel#WARN}.
040 *
041 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
042 * @org.apache.xbean.XBean
043 */
044public class LoggingFilter extends IoFilterAdapter {
045    /** The logger name */
046    private final String name;
047
048    /** The logger */
049    private final Logger logger;
050
051    /** The log level for the exceptionCaught event. Default to WARN. */
052    private LogLevel exceptionCaughtLevel = LogLevel.WARN;
053
054    /** The log level for the messageSent event. Default to INFO. */
055    private LogLevel messageSentLevel = LogLevel.INFO;
056
057    /** The log level for the messageReceived event. Default to INFO. */
058    private LogLevel messageReceivedLevel = LogLevel.INFO;
059
060    /** The log level for the sessionCreated event. Default to INFO. */
061    private LogLevel sessionCreatedLevel = LogLevel.INFO;
062
063    /** The log level for the sessionOpened event. Default to INFO. */
064    private LogLevel sessionOpenedLevel = LogLevel.INFO;
065
066    /** The log level for the sessionIdle event. Default to INFO. */
067    private LogLevel sessionIdleLevel = LogLevel.INFO;
068
069    /** The log level for the sessionClosed event. Default to INFO. */
070    private LogLevel sessionClosedLevel = LogLevel.INFO;
071
072    /**
073     * Default Constructor.
074     */
075    public LoggingFilter() {
076        this(LoggingFilter.class.getName());
077    }
078
079    /**
080     * Create a new NoopFilter using a class name
081     * 
082     * @param clazz the cass which name will be used to create the logger
083     */
084    public LoggingFilter(Class<?> clazz) {
085        this(clazz.getName());
086    }
087
088    /**
089     * Create a new NoopFilter using a name
090     * 
091     * @param name the name used to create the logger. If null, will default to "NoopFilter"
092     */
093    public LoggingFilter(String name) {
094        if (name == null) {
095            this.name = LoggingFilter.class.getName();
096        } else {
097            this.name = name;
098        }
099
100        logger = LoggerFactory.getLogger(this.name);
101    }
102
103    /**
104     * @return The logger's name
105     */
106    public String getName() {
107        return name;
108    }
109
110    /**
111     * Log if the logger and the current event log level are compatible. We log
112     * a message and an exception.
113     * 
114     * @param eventLevel the event log level as requested by the user
115     * @param message the message to log
116     * @param cause the exception cause to log
117     */
118    private void log(LogLevel eventLevel, String message, Throwable cause) {
119        switch (eventLevel) {
120        case TRACE:
121            logger.trace(message, cause);
122            return;
123        case DEBUG:
124            logger.debug(message, cause);
125            return;
126        case INFO:
127            logger.info(message, cause);
128            return;
129        case WARN:
130            logger.warn(message, cause);
131            return;
132        case ERROR:
133            logger.error(message, cause);
134            return;
135        default:
136            return;
137        }
138    }
139
140    /**
141     * Log if the logger and the current event log level are compatible. We log
142     * a formated message and its parameters.
143     * 
144     * @param eventLevel the event log level as requested by the user
145     * @param message the formated message to log
146     * @param param the parameter injected into the message
147     */
148    private void log(LogLevel eventLevel, String message, Object param) {
149        switch (eventLevel) {
150        case TRACE:
151            logger.trace(message, param);
152            return;
153        case DEBUG:
154            logger.debug(message, param);
155            return;
156        case INFO:
157            logger.info(message, param);
158            return;
159        case WARN:
160            logger.warn(message, param);
161            return;
162        case ERROR:
163            logger.error(message, param);
164            return;
165        default:
166            return;
167        }
168    }
169
170    /**
171     * Log if the logger and the current event log level are compatible. We log
172     * a simple message.
173     * 
174     * @param eventLevel the event log level as requested by the user
175     * @param message the message to log
176     */
177    private void log(LogLevel eventLevel, String message) {
178        switch (eventLevel) {
179        case TRACE:
180            logger.trace(message);
181            return;
182        case DEBUG:
183            logger.debug(message);
184            return;
185        case INFO:
186            logger.info(message);
187            return;
188        case WARN:
189            logger.warn(message);
190            return;
191        case ERROR:
192            logger.error(message);
193            return;
194        default:
195            return;
196        }
197    }
198
199    @Override
200    public void exceptionCaught(NextFilter nextFilter, IoSession session, Throwable cause) throws Exception {
201        log(exceptionCaughtLevel, "EXCEPTION :", cause);
202        nextFilter.exceptionCaught(session, cause);
203    }
204
205    @Override
206    public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception {
207        log(messageReceivedLevel, "RECEIVED: {}", message);
208        nextFilter.messageReceived(session, message);
209    }
210
211    @Override
212    public void messageSent(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception {
213        log(messageSentLevel, "SENT: {}", writeRequest.getOriginalRequest().getMessage());
214        nextFilter.messageSent(session, writeRequest);
215    }
216
217    @Override
218    public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception {
219        log(sessionCreatedLevel, "CREATED");
220        nextFilter.sessionCreated(session);
221    }
222
223    @Override
224    public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception {
225        log(sessionOpenedLevel, "OPENED");
226        nextFilter.sessionOpened(session);
227    }
228
229    @Override
230    public void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status) throws Exception {
231        log(sessionIdleLevel, "IDLE");
232        nextFilter.sessionIdle(session, status);
233    }
234
235    @Override
236    public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception {
237        log(sessionClosedLevel, "CLOSED");
238        nextFilter.sessionClosed(session);
239    }
240
241    /**
242     * Set the LogLevel for the ExceptionCaught event.
243     * 
244     * @param level The LogLevel to set
245     */
246    public void setExceptionCaughtLogLevel(LogLevel level) {
247        exceptionCaughtLevel = level;
248    }
249
250    /**
251     * Get the LogLevel for the ExceptionCaught event.
252     * 
253     * @return The LogLevel for the ExceptionCaught eventType
254     */
255    public LogLevel getExceptionCaughtLogLevel() {
256        return exceptionCaughtLevel;
257    }
258
259    /**
260     * Set the LogLevel for the MessageReceived event.
261     * 
262     * @param level The LogLevel to set
263     */
264    public void setMessageReceivedLogLevel(LogLevel level) {
265        messageReceivedLevel = level;
266    }
267
268    /**
269     * Get the LogLevel for the MessageReceived event.
270     * 
271     * @return The LogLevel for the MessageReceived eventType
272     */
273    public LogLevel getMessageReceivedLogLevel() {
274        return messageReceivedLevel;
275    }
276
277    /**
278     * Set the LogLevel for the MessageSent event.
279     * 
280     * @param level The LogLevel to set
281     */
282    public void setMessageSentLogLevel(LogLevel level) {
283        messageSentLevel = level;
284    }
285
286    /**
287     * Get the LogLevel for the MessageSent event.
288     * 
289     * @return The LogLevel for the MessageSent eventType
290     */
291    public LogLevel getMessageSentLogLevel() {
292        return messageSentLevel;
293    }
294
295    /**
296     * Set the LogLevel for the SessionCreated event.
297     * 
298     * @param level The LogLevel to set
299     */
300    public void setSessionCreatedLogLevel(LogLevel level) {
301        sessionCreatedLevel = level;
302    }
303
304    /**
305     * Get the LogLevel for the SessionCreated event.
306     * 
307     * @return The LogLevel for the SessionCreated eventType
308     */
309    public LogLevel getSessionCreatedLogLevel() {
310        return sessionCreatedLevel;
311    }
312
313    /**
314     * Set the LogLevel for the SessionOpened event.
315     * 
316     * @param level The LogLevel to set
317     */
318    public void setSessionOpenedLogLevel(LogLevel level) {
319        sessionOpenedLevel = level;
320    }
321
322    /**
323     * Get the LogLevel for the SessionOpened event.
324     * 
325     * @return The LogLevel for the SessionOpened eventType
326     */
327    public LogLevel getSessionOpenedLogLevel() {
328        return sessionOpenedLevel;
329    }
330
331    /**
332     * Set the LogLevel for the SessionIdle event.
333     * 
334     * @param level The LogLevel to set
335     */
336    public void setSessionIdleLogLevel(LogLevel level) {
337        sessionIdleLevel = level;
338    }
339
340    /**
341     * Get the LogLevel for the SessionIdle event.
342     * 
343     * @return The LogLevel for the SessionIdle eventType
344     */
345    public LogLevel getSessionIdleLogLevel() {
346        return sessionIdleLevel;
347    }
348
349    /**
350     * Set the LogLevel for the SessionClosed event.
351     * 
352     * @param level The LogLevel to set
353     */
354    public void setSessionClosedLogLevel(LogLevel level) {
355        sessionClosedLevel = level;
356    }
357
358    /**
359     * Get the LogLevel for the SessionClosed event.
360     * 
361     * @return The LogLevel for the SessionClosed eventType
362     */
363    public LogLevel getSessionClosedLogLevel() {
364        return sessionClosedLevel;
365    }
366}