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.LoggingEvent;
035import org.slf4j.event.SubstituteLoggingEvent;
036
037/**
038 * A logger implementation which logs via a delegate logger. By default, the delegate is a
039 * {@link NOPLogger}. However, a different delegate can be set at any time.
040 * <p/>
041 * See also the <a href="http://www.slf4j.org/codes.html#substituteLogger">relevant
042 * error code</a> documentation.
043 *
044 * @author Chetan Mehrotra
045 * @author Ceki Gulcu
046 */
047public class SubstituteLogger implements Logger {
048
049    private final String name;
050    private volatile Logger _delegate;
051    private Boolean delegateEventAware;
052    private Method logMethodCache;
053    private EventRecodingLogger eventRecodingLogger;
054    private Queue<SubstituteLoggingEvent> eventQueue;
055
056    private final boolean createdPostInitialization;
057    
058    public SubstituteLogger(String name, Queue<SubstituteLoggingEvent> eventQueue, boolean createdPostInitialization) {
059        this.name = name;
060        this.eventQueue = eventQueue;
061        this.createdPostInitialization = createdPostInitialization;
062    }
063
064    public String getName() {
065        return name;
066    }
067
068    public boolean isTraceEnabled() {
069        return delegate().isTraceEnabled();
070    }
071
072    public void trace(String msg) {
073        delegate().trace(msg);
074    }
075
076    public void trace(String format, Object arg) {
077        delegate().trace(format, arg);
078    }
079
080    public void trace(String format, Object arg1, Object arg2) {
081        delegate().trace(format, arg1, arg2);
082    }
083
084    public void trace(String format, Object... arguments) {
085        delegate().trace(format, arguments);
086    }
087
088    public void trace(String msg, Throwable t) {
089        delegate().trace(msg, t);
090    }
091
092    public boolean isTraceEnabled(Marker marker) {
093        return delegate().isTraceEnabled(marker);
094    }
095
096    public void trace(Marker marker, String msg) {
097        delegate().trace(marker, msg);
098    }
099
100    public void trace(Marker marker, String format, Object arg) {
101        delegate().trace(marker, format, arg);
102    }
103
104    public void trace(Marker marker, String format, Object arg1, Object arg2) {
105        delegate().trace(marker, format, arg1, arg2);
106    }
107
108    public void trace(Marker marker, String format, Object... arguments) {
109        delegate().trace(marker, format, arguments);
110    }
111
112    public void trace(Marker marker, String msg, Throwable t) {
113        delegate().trace(marker, msg, t);
114    }
115
116    public boolean isDebugEnabled() {
117        return delegate().isDebugEnabled();
118    }
119
120    public void debug(String msg) {
121        delegate().debug(msg);
122    }
123
124    public void debug(String format, Object arg) {
125        delegate().debug(format, arg);
126    }
127
128    public void debug(String format, Object arg1, Object arg2) {
129        delegate().debug(format, arg1, arg2);
130    }
131
132    public void debug(String format, Object... arguments) {
133        delegate().debug(format, arguments);
134    }
135
136    public void debug(String msg, Throwable t) {
137        delegate().debug(msg, t);
138    }
139
140    public boolean isDebugEnabled(Marker marker) {
141        return delegate().isDebugEnabled(marker);
142    }
143
144    public void debug(Marker marker, String msg) {
145        delegate().debug(marker, msg);
146    }
147
148    public void debug(Marker marker, String format, Object arg) {
149        delegate().debug(marker, format, arg);
150    }
151
152    public void debug(Marker marker, String format, Object arg1, Object arg2) {
153        delegate().debug(marker, format, arg1, arg2);
154    }
155
156    public void debug(Marker marker, String format, Object... arguments) {
157        delegate().debug(marker, format, arguments);
158    }
159
160    public void debug(Marker marker, String msg, Throwable t) {
161        delegate().debug(marker, msg, t);
162    }
163
164    public boolean isInfoEnabled() {
165        return delegate().isInfoEnabled();
166    }
167
168    public void info(String msg) {
169        delegate().info(msg);
170    }
171
172    public void info(String format, Object arg) {
173        delegate().info(format, arg);
174    }
175
176    public void info(String format, Object arg1, Object arg2) {
177        delegate().info(format, arg1, arg2);
178    }
179
180    public void info(String format, Object... arguments) {
181        delegate().info(format, arguments);
182    }
183
184    public void info(String msg, Throwable t) {
185        delegate().info(msg, t);
186    }
187
188    public boolean isInfoEnabled(Marker marker) {
189        return delegate().isInfoEnabled(marker);
190    }
191
192    public void info(Marker marker, String msg) {
193        delegate().info(marker, msg);
194    }
195
196    public void info(Marker marker, String format, Object arg) {
197        delegate().info(marker, format, arg);
198    }
199
200    public void info(Marker marker, String format, Object arg1, Object arg2) {
201        delegate().info(marker, format, arg1, arg2);
202    }
203
204    public void info(Marker marker, String format, Object... arguments) {
205        delegate().info(marker, format, arguments);
206    }
207
208    public void info(Marker marker, String msg, Throwable t) {
209        delegate().info(marker, msg, t);
210    }
211
212    public boolean isWarnEnabled() {
213        return delegate().isWarnEnabled();
214    }
215
216    public void warn(String msg) {
217        delegate().warn(msg);
218    }
219
220    public void warn(String format, Object arg) {
221        delegate().warn(format, arg);
222    }
223
224    public void warn(String format, Object arg1, Object arg2) {
225        delegate().warn(format, arg1, arg2);
226    }
227
228    public void warn(String format, Object... arguments) {
229        delegate().warn(format, arguments);
230    }
231
232    public void warn(String msg, Throwable t) {
233        delegate().warn(msg, t);
234    }
235
236    public boolean isWarnEnabled(Marker marker) {
237        return delegate().isWarnEnabled(marker);
238    }
239
240    public void warn(Marker marker, String msg) {
241        delegate().warn(marker, msg);
242    }
243
244    public void warn(Marker marker, String format, Object arg) {
245        delegate().warn(marker, format, arg);
246    }
247
248    public void warn(Marker marker, String format, Object arg1, Object arg2) {
249        delegate().warn(marker, format, arg1, arg2);
250    }
251
252    public void warn(Marker marker, String format, Object... arguments) {
253        delegate().warn(marker, format, arguments);
254    }
255
256    public void warn(Marker marker, String msg, Throwable t) {
257        delegate().warn(marker, msg, t);
258    }
259
260    public boolean isErrorEnabled() {
261        return delegate().isErrorEnabled();
262    }
263
264    public void error(String msg) {
265        delegate().error(msg);
266    }
267
268    public void error(String format, Object arg) {
269        delegate().error(format, arg);
270    }
271
272    public void error(String format, Object arg1, Object arg2) {
273        delegate().error(format, arg1, arg2);
274    }
275
276    public void error(String format, Object... arguments) {
277        delegate().error(format, arguments);
278    }
279
280    public void error(String msg, Throwable t) {
281        delegate().error(msg, t);
282    }
283
284    public boolean isErrorEnabled(Marker marker) {
285        return delegate().isErrorEnabled(marker);
286    }
287
288    public void error(Marker marker, String msg) {
289        delegate().error(marker, msg);
290    }
291
292    public void error(Marker marker, String format, Object arg) {
293        delegate().error(marker, format, arg);
294    }
295
296    public void error(Marker marker, String format, Object arg1, Object arg2) {
297        delegate().error(marker, format, arg1, arg2);
298    }
299
300    public void error(Marker marker, String format, Object... arguments) {
301        delegate().error(marker, format, arguments);
302    }
303
304    public void error(Marker marker, String msg, Throwable t) {
305        delegate().error(marker, msg, t);
306    }
307
308    @Override
309    public boolean equals(Object o) {
310        if (this == o)
311            return true;
312        if (o == null || getClass() != o.getClass())
313            return false;
314
315        SubstituteLogger that = (SubstituteLogger) o;
316
317        if (!name.equals(that.name))
318            return false;
319
320        return true;
321    }
322
323    @Override
324    public int hashCode() {
325        return name.hashCode();
326    }
327
328    /**
329     * Return the delegate logger instance if set. Otherwise, return a {@link NOPLogger}
330     * instance.
331     */
332    public Logger delegate() {
333        if(_delegate != null) {
334            return _delegate;
335        }
336        if(createdPostInitialization) {
337            return NOPLogger.NOP_LOGGER;
338        } else {
339            return getEventRecordingLogger();
340        }
341    }
342
343    private Logger getEventRecordingLogger() {
344        if (eventRecodingLogger == null) {
345            eventRecodingLogger = new EventRecodingLogger(this, eventQueue);
346        }
347        return eventRecodingLogger;
348    }
349
350    /**
351     * Typically called after the {@link org.slf4j.LoggerFactory} initialization phase is completed.
352     * @param delegate
353     */
354    public void setDelegate(Logger delegate) {
355        this._delegate = delegate;
356    }
357
358    public boolean isDelegateEventAware() {
359        if (delegateEventAware != null)
360            return delegateEventAware;
361
362        try {
363            logMethodCache = _delegate.getClass().getMethod("log", LoggingEvent.class);
364            delegateEventAware = Boolean.TRUE;
365        } catch (NoSuchMethodException e) {
366            delegateEventAware = Boolean.FALSE;
367        }
368        return delegateEventAware;
369    }
370
371    public void log(LoggingEvent event) {
372        if (isDelegateEventAware()) {
373            try {
374                logMethodCache.invoke(_delegate, event);
375            } catch (IllegalAccessException e) {
376            } catch (IllegalArgumentException e) {
377            } catch (InvocationTargetException e) {
378            }
379        }
380    }
381
382
383    public boolean isDelegateNull() {
384        return _delegate == null;
385    }
386
387    public boolean isDelegateNOP() {
388        return _delegate instanceof NOPLogger;
389    }
390}