001/**
002 * Copyright (c) 2004-2011 QOS.ch
003 * All rights reserved.
004 *
005 * Permission is hereby granted, free  of charge, to any person obtaining
006 * a  copy  of this  software  and  associated  documentation files  (the
007 * "Software"), to  deal in  the Software without  restriction, including
008 * without limitation  the rights to  use, copy, modify,  merge, publish,
009 * distribute,  sublicense, and/or sell  copies of  the Software,  and to
010 * permit persons to whom the Software  is furnished to do so, subject to
011 * the following conditions:
012 *
013 * The  above  copyright  notice  and  this permission  notice  shall  be
014 * included in all copies or substantial portions of the Software.
015 *
016 * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
017 * EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
018 * MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
019 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
020 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
021 * OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
022 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
023 *
024 */
025package org.slf4j.helpers;
026
027import java.lang.reflect.InvocationTargetException;
028import java.lang.reflect.Method;
029import java.util.Queue;
030
031import org.slf4j.Logger;
032import org.slf4j.Marker;
033import org.slf4j.event.EventRecodingLogger;
034import org.slf4j.event.Level;
035import org.slf4j.event.LoggingEvent;
036import org.slf4j.event.SubstituteLoggingEvent;
037import org.slf4j.spi.LoggingEventBuilder;
038
039/**
040 * A logger implementation which logs via a delegate logger. By default, the delegate is a
041 * {@link NOPLogger}. However, a different delegate can be set at any time.
042 * 
043 * <p>See also the <a href="http://www.slf4j.org/codes.html#substituteLogger">relevant
044 * error code</a> documentation.
045 *
046 * @author Chetan Mehrotra
047 * @author Ceki Gulcu
048 */
049public class SubstituteLogger implements Logger {
050
051    private final String name;
052    private volatile Logger _delegate;
053    private Boolean delegateEventAware;
054    private Method logMethodCache;
055    private EventRecodingLogger eventRecodingLogger;
056    private final Queue<SubstituteLoggingEvent> eventQueue;
057
058    public final boolean createdPostInitialization;
059
060    public SubstituteLogger(String name, Queue<SubstituteLoggingEvent> eventQueue, boolean createdPostInitialization) {
061        this.name = name;
062        this.eventQueue = eventQueue;
063        this.createdPostInitialization = createdPostInitialization;
064    }
065
066    @Override
067    public String getName() {
068        return name;
069    }
070    
071    @Override
072    public LoggingEventBuilder makeLoggingEventBuilder(Level level) {
073        return delegate().makeLoggingEventBuilder(level);
074    }
075
076    @Override
077    public LoggingEventBuilder atLevel(Level level) {
078        return delegate().atLevel(level); 
079    }
080    
081    @Override
082    public boolean isEnabledForLevel(Level level) {
083        return delegate().isEnabledForLevel(level);
084    }
085    
086    @Override
087    public boolean isTraceEnabled() {
088        return delegate().isTraceEnabled();
089    }
090    
091    @Override
092    public void trace(String msg) {
093        delegate().trace(msg);
094    }
095    
096    @Override
097    public void trace(String format, Object arg) {
098        delegate().trace(format, arg);
099    }
100    
101    @Override
102    public void trace(String format, Object arg1, Object arg2) {
103        delegate().trace(format, arg1, arg2);
104    }
105    
106    @Override
107    public void trace(String format, Object... arguments) {
108        delegate().trace(format, arguments);
109    } 
110    
111    @Override
112    public void trace(String msg, Throwable t) {
113        delegate().trace(msg, t);
114    }
115    
116    @Override
117    public boolean isTraceEnabled(Marker marker) {
118        return delegate().isTraceEnabled(marker);
119    }
120    
121    @Override
122    public void trace(Marker marker, String msg) {
123        delegate().trace(marker, msg);
124    }
125    
126    @Override
127    public void trace(Marker marker, String format, Object arg) {
128        delegate().trace(marker, format, arg);
129    }
130    
131    @Override
132    public void trace(Marker marker, String format, Object arg1, Object arg2) {
133        delegate().trace(marker, format, arg1, arg2);
134    }
135    @Override
136    public void trace(Marker marker, String format, Object... arguments) {
137        delegate().trace(marker, format, arguments);
138    }
139    @Override
140    public void trace(Marker marker, String msg, Throwable t) {
141        delegate().trace(marker, msg, t);
142    }
143    
144    @Override
145    public LoggingEventBuilder atTrace() {
146        return delegate().atTrace();
147    }
148    
149    @Override
150    public boolean isDebugEnabled() {
151        return delegate().isDebugEnabled();
152    }
153    
154    @Override
155    public void debug(String msg) {
156        delegate().debug(msg);
157    }
158    
159    @Override
160    public void debug(String format, Object arg) {
161        delegate().debug(format, arg);
162    }
163    
164    @Override
165    public void debug(String format, Object arg1, Object arg2) {
166        delegate().debug(format, arg1, arg2);
167    }
168    
169    @Override
170    public void debug(String format, Object... arguments) {
171        delegate().debug(format, arguments);
172    }
173    
174    @Override
175    public void debug(String msg, Throwable t) {
176        delegate().debug(msg, t);
177    }
178    
179    @Override
180    public boolean isDebugEnabled(Marker marker) {
181        return delegate().isDebugEnabled(marker);
182    }
183    
184    @Override
185    public void debug(Marker marker, String msg) {
186        delegate().debug(marker, msg);
187    }
188    
189    @Override
190    public void debug(Marker marker, String format, Object arg) {
191        delegate().debug(marker, format, arg);
192    }
193    
194    @Override
195    public void debug(Marker marker, String format, Object arg1, Object arg2) {
196        delegate().debug(marker, format, arg1, arg2);
197    }
198    
199    @Override
200    public void debug(Marker marker, String format, Object... arguments) {
201        delegate().debug(marker, format, arguments);
202    }
203    
204    @Override
205    public void debug(Marker marker, String msg, Throwable t) {
206        delegate().debug(marker, msg, t);
207    }
208    
209    @Override
210    public LoggingEventBuilder atDebug() {
211        return delegate().atDebug();
212    }
213    
214    @Override
215    public boolean isInfoEnabled() {
216        return delegate().isInfoEnabled();
217    }
218
219    
220    @Override
221    public void info(String msg) {
222        delegate().info(msg);
223    }
224    
225    @Override
226    public void info(String format, Object arg) {
227        delegate().info(format, arg);
228    }
229    
230    @Override
231    public void info(String format, Object arg1, Object arg2) {
232        delegate().info(format, arg1, arg2);
233    }
234    
235    @Override
236    public void info(String format, Object... arguments) {
237        delegate().info(format, arguments);
238    }
239    
240    @Override
241    public void info(String msg, Throwable t) {
242        delegate().info(msg, t);
243    }
244    
245    @Override
246    public boolean isInfoEnabled(Marker marker) {
247        return delegate().isInfoEnabled(marker);
248    }
249    
250    @Override
251    public void info(Marker marker, String msg) {
252        delegate().info(marker, msg);
253    }
254    
255    @Override
256    public void info(Marker marker, String format, Object arg) {
257        delegate().info(marker, format, arg);
258    }
259    
260    @Override
261    public void info(Marker marker, String format, Object arg1, Object arg2) {
262        delegate().info(marker, format, arg1, arg2);
263    }
264    
265    @Override
266    public void info(Marker marker, String format, Object... arguments) {
267        delegate().info(marker, format, arguments);
268    }
269    
270    @Override
271    public void info(Marker marker, String msg, Throwable t) {
272        delegate().info(marker, msg, t);
273    }
274    
275    @Override
276    public LoggingEventBuilder atInfo() {
277        return delegate().atInfo();
278    }
279
280    
281    @Override
282    public boolean isWarnEnabled() {
283        return delegate().isWarnEnabled();
284    }
285    
286    @Override
287    public void warn(String msg) {
288        delegate().warn(msg);
289    }
290    
291    @Override
292    public void warn(String format, Object arg) {
293        delegate().warn(format, arg);
294    }
295    
296    @Override
297    public void warn(String format, Object arg1, Object arg2) {
298        delegate().warn(format, arg1, arg2);
299    }
300    
301    @Override
302    public void warn(String format, Object... arguments) {
303        delegate().warn(format, arguments);
304    }
305    
306    @Override
307    public void warn(String msg, Throwable t) {
308        delegate().warn(msg, t);
309    }
310
311    public boolean isWarnEnabled(Marker marker) {
312        return delegate().isWarnEnabled(marker);
313    }
314    
315    @Override
316    public void warn(Marker marker, String msg) {
317        delegate().warn(marker, msg);
318    }
319    
320    @Override
321    public void warn(Marker marker, String format, Object arg) {
322        delegate().warn(marker, format, arg);
323    }
324    
325    @Override
326    public void warn(Marker marker, String format, Object arg1, Object arg2) {
327        delegate().warn(marker, format, arg1, arg2);
328    }
329    
330    @Override
331    public void warn(Marker marker, String format, Object... arguments) {
332        delegate().warn(marker, format, arguments);
333    }
334    
335    @Override
336    public void warn(Marker marker, String msg, Throwable t) {
337        delegate().warn(marker, msg, t);
338    }
339    
340    @Override
341    public LoggingEventBuilder atWarn() {
342        return delegate().atWarn();
343    }
344
345    
346    
347    @Override
348    public boolean isErrorEnabled() {
349        return delegate().isErrorEnabled();
350    }
351    
352    @Override
353    public void error(String msg) {
354        delegate().error(msg);
355    }
356    
357    @Override
358    public void error(String format, Object arg) {
359        delegate().error(format, arg);
360    }
361    
362    @Override
363    public void error(String format, Object arg1, Object arg2) {
364        delegate().error(format, arg1, arg2);
365    }
366    
367    @Override
368    public void error(String format, Object... arguments) {
369        delegate().error(format, arguments);
370    }
371    
372    @Override
373    public void error(String msg, Throwable t) {
374        delegate().error(msg, t);
375    }
376    
377    @Override
378    public boolean isErrorEnabled(Marker marker) {
379        return delegate().isErrorEnabled(marker);
380    }
381    
382    @Override
383    public void error(Marker marker, String msg) {
384        delegate().error(marker, msg);
385    }
386    
387    @Override
388    public void error(Marker marker, String format, Object arg) {
389        delegate().error(marker, format, arg);
390    }
391    
392    @Override
393    public void error(Marker marker, String format, Object arg1, Object arg2) {
394        delegate().error(marker, format, arg1, arg2);
395    }
396    
397    @Override
398    public void error(Marker marker, String format, Object... arguments) {
399        delegate().error(marker, format, arguments);
400    }
401    
402    @Override
403    public void error(Marker marker, String msg, Throwable t) {
404        delegate().error(marker, msg, t);
405    }
406
407    @Override
408    public LoggingEventBuilder atError() {
409        return delegate().atError();
410    }
411    
412    @Override
413    public boolean equals(Object o) {
414        if (this == o)
415            return true;
416        if (o == null || getClass() != o.getClass())
417            return false;
418
419        SubstituteLogger that = (SubstituteLogger) o;
420
421        if (!name.equals(that.name))
422            return false;
423
424        return true;
425    }
426
427    @Override
428    public int hashCode() {
429        return name.hashCode();
430    }
431
432    /**
433     * Return the delegate logger instance if set. Otherwise, return a {@link NOPLogger}
434     * instance.
435     */
436    public Logger delegate() {
437        if (_delegate != null) {
438            return _delegate;
439        }
440        if (createdPostInitialization) {
441            return NOPLogger.NOP_LOGGER;
442        } else {
443            return getEventRecordingLogger();
444        }
445    }
446
447    private Logger getEventRecordingLogger() {
448        if (eventRecodingLogger == null) {
449            eventRecodingLogger = new EventRecodingLogger(this, eventQueue);
450        }
451        return eventRecodingLogger;
452    }
453
454    /**
455     * Typically called after the {@link org.slf4j.LoggerFactory} initialization phase is completed.
456     * @param delegate
457     */
458    public void setDelegate(Logger delegate) {
459        this._delegate = delegate;
460    }
461
462    public boolean isDelegateEventAware() {
463        if (delegateEventAware != null)
464            return delegateEventAware;
465
466        try {
467            logMethodCache = _delegate.getClass().getMethod("log", LoggingEvent.class);
468            delegateEventAware = Boolean.TRUE;
469        } catch (NoSuchMethodException e) {
470            delegateEventAware = Boolean.FALSE;
471        }
472        return delegateEventAware;
473    }
474    
475    public void log(LoggingEvent event) {
476        if (isDelegateEventAware()) {
477            try {
478                logMethodCache.invoke(_delegate, event);
479            } catch (IllegalAccessException e) {
480            } catch (IllegalArgumentException e) {
481            } catch (InvocationTargetException e) {
482            }
483        }
484    }
485
486    public boolean isDelegateNull() {
487        return _delegate == null;
488    }
489
490    public boolean isDelegateNOP() {
491        return _delegate instanceof NOPLogger;
492    }
493}