001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache license, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the license for the specific language governing permissions and
015 * limitations under the license.
016 */
017package org.apache.logging.slf4j;
018
019import java.io.IOException;
020import java.io.ObjectInputStream;
021import java.io.ObjectOutputStream;
022import java.io.Serializable;
023
024import org.apache.logging.log4j.Level;
025import org.apache.logging.log4j.LogManager;
026import org.apache.logging.log4j.message.Message;
027import org.apache.logging.log4j.message.ParameterizedMessage;
028import org.apache.logging.log4j.message.SimpleMessage;
029import org.apache.logging.log4j.spi.ExtendedLogger;
030import org.apache.logging.log4j.util.LoaderUtil;
031import org.slf4j.Marker;
032import org.slf4j.MarkerFactory;
033import org.slf4j.spi.LocationAwareLogger;
034
035/**
036 * SLF4J logger implementation that uses Log4j.
037 */
038public class Log4jLogger implements LocationAwareLogger, Serializable {
039
040    public static final String FQCN = Log4jLogger.class.getName();
041
042    private static final long serialVersionUID = 7869000638091304316L;
043    private static final Marker EVENT_MARKER = MarkerFactory.getMarker("EVENT");
044    private final boolean eventLogger;
045    private transient ExtendedLogger logger;
046    private final String name;
047    private transient EventDataConverter converter;
048    private transient Log4jMarkerFactory markerFactory;
049
050    public Log4jLogger(final Log4jMarkerFactory markerFactory, final ExtendedLogger logger, final String name) {
051        this.markerFactory = markerFactory;
052        this.logger = logger;
053        this.eventLogger = "EventLogger".equals(name);
054        this.name = name;
055        this.converter = createConverter();
056    }
057
058    @Override
059    public void trace(final String format) {
060        logger.logIfEnabled(FQCN, Level.TRACE, null, format);
061    }
062
063    @Override
064    public void trace(final String format, final Object o) {
065        logger.logIfEnabled(FQCN, Level.TRACE, null, format, o);
066    }
067
068    @Override
069    public void trace(final String format, final Object arg1, final Object arg2) {
070        logger.logIfEnabled(FQCN, Level.TRACE, null, format, arg1, arg2);
071    }
072
073    @Override
074    public void trace(final String format, final Object... args) {
075        logger.logIfEnabled(FQCN, Level.TRACE, null, format, args);
076    }
077
078    @Override
079    public void trace(final String format, final Throwable t) {
080        logger.logIfEnabled(FQCN, Level.TRACE, null, format, t);
081    }
082
083    @Override
084    public boolean isTraceEnabled() {
085        return logger.isEnabled(Level.TRACE, null, null);
086    }
087
088    @Override
089    public boolean isTraceEnabled(final Marker marker) {
090        return logger.isEnabled(Level.TRACE, getMarker(marker), null);
091    }
092
093    @Override
094    public void trace(final Marker marker, final String s) {
095        logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s);
096    }
097
098    @Override
099    public void trace(final Marker marker, final String s, final Object o) {
100        logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, o);
101    }
102
103    @Override
104    public void trace(final Marker marker, final String s, final Object o, final Object o1) {
105        logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, o, o1);
106    }
107
108    @Override
109    public void trace(final Marker marker, final String s, final Object... objects) {
110        logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, objects);
111    }
112
113    @Override
114    public void trace(final Marker marker, final String s, final Throwable throwable) {
115        logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, throwable);
116    }
117
118    @Override
119    public void debug(final String format) {
120        logger.logIfEnabled(FQCN, Level.DEBUG, null, format);
121    }
122
123    @Override
124    public void debug(final String format, final Object o) {
125        logger.logIfEnabled(FQCN, Level.DEBUG, null, format, o);
126    }
127
128    @Override
129    public void debug(final String format, final Object arg1, final Object arg2) {
130        logger.logIfEnabled(FQCN, Level.DEBUG, null, format, arg1, arg2);
131    }
132
133    @Override
134    public void debug(final String format, final Object... args) {
135        logger.logIfEnabled(FQCN, Level.DEBUG, null, format, args);
136    }
137
138    @Override
139    public void debug(final String format, final Throwable t) {
140        logger.logIfEnabled(FQCN, Level.DEBUG, null, format, t);
141    }
142
143    @Override
144    public boolean isDebugEnabled() {
145        return logger.isEnabled(Level.DEBUG, null, null);
146    }
147
148    @Override
149    public boolean isDebugEnabled(final Marker marker) {
150        return logger.isEnabled(Level.DEBUG, getMarker(marker), null);
151    }
152
153    @Override
154    public void debug(final Marker marker, final String s) {
155        logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s);
156    }
157
158    @Override
159    public void debug(final Marker marker, final String s, final Object o) {
160        logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, o);
161    }
162
163    @Override
164    public void debug(final Marker marker, final String s, final Object o, final Object o1) {
165        logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, o, o1);
166    }
167
168    @Override
169    public void debug(final Marker marker, final String s, final Object... objects) {
170        logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, objects);
171    }
172
173    @Override
174    public void debug(final Marker marker, final String s, final Throwable throwable) {
175        logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, throwable);
176    }
177
178    @Override
179    public void info(final String format) {
180        logger.logIfEnabled(FQCN, Level.INFO, null, format);
181    }
182
183    @Override
184    public void info(final String format, final Object o) {
185        logger.logIfEnabled(FQCN, Level.INFO, null, format, o);
186    }
187
188    @Override
189    public void info(final String format, final Object arg1, final Object arg2) {
190        logger.logIfEnabled(FQCN, Level.INFO, null, format, arg1, arg2);
191    }
192
193    @Override
194    public void info(final String format, final Object... args) {
195        logger.logIfEnabled(FQCN, Level.INFO, null, format, args);
196    }
197
198    @Override
199    public void info(final String format, final Throwable t) {
200        logger.logIfEnabled(FQCN, Level.INFO, null, format, t);
201    }
202
203    @Override
204    public boolean isInfoEnabled() {
205        return logger.isEnabled(Level.INFO, null, null);
206    }
207
208    @Override
209    public boolean isInfoEnabled(final Marker marker) {
210        return logger.isEnabled(Level.INFO, getMarker(marker), null);
211    }
212
213    @Override
214    public void info(final Marker marker, final String s) {
215        logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s);
216    }
217
218    @Override
219    public void info(final Marker marker, final String s, final Object o) {
220        logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, o);
221    }
222
223    @Override
224    public void info(final Marker marker, final String s, final Object o, final Object o1) {
225        logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, o, o1);
226    }
227
228    @Override
229    public void info(final Marker marker, final String s, final Object... objects) {
230        logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, objects);
231    }
232
233    @Override
234    public void info(final Marker marker, final String s, final Throwable throwable) {
235        logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, throwable);
236    }
237
238    @Override
239    public void warn(final String format) {
240        logger.logIfEnabled(FQCN, Level.WARN, null, format);
241    }
242
243    @Override
244    public void warn(final String format, final Object o) {
245        logger.logIfEnabled(FQCN, Level.WARN, null, format, o);
246    }
247
248    @Override
249    public void warn(final String format, final Object arg1, final Object arg2) {
250        logger.logIfEnabled(FQCN, Level.WARN, null, format, arg1, arg2);
251    }
252
253    @Override
254    public void warn(final String format, final Object... args) {
255        logger.logIfEnabled(FQCN, Level.WARN, null, format, args);
256    }
257
258    @Override
259    public void warn(final String format, final Throwable t) {
260        logger.logIfEnabled(FQCN, Level.WARN, null, format, t);
261    }
262
263    @Override
264    public boolean isWarnEnabled() {
265        return logger.isEnabled(Level.WARN, null, null);
266    }
267
268    @Override
269    public boolean isWarnEnabled(final Marker marker) {
270        return logger.isEnabled(Level.WARN, getMarker(marker), null);
271    }
272
273    @Override
274    public void warn(final Marker marker, final String s) {
275        logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s);
276    }
277
278    @Override
279    public void warn(final Marker marker, final String s, final Object o) {
280        logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, o);
281    }
282
283    @Override
284    public void warn(final Marker marker, final String s, final Object o, final Object o1) {
285        logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, o, o1);
286    }
287
288    @Override
289    public void warn(final Marker marker, final String s, final Object... objects) {
290        logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, objects);
291    }
292
293    @Override
294    public void warn(final Marker marker, final String s, final Throwable throwable) {
295        logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, throwable);
296    }
297
298    @Override
299    public void error(final String format) {
300        logger.logIfEnabled(FQCN, Level.ERROR, null, format);
301    }
302
303    @Override
304    public void error(final String format, final Object o) {
305        logger.logIfEnabled(FQCN, Level.ERROR, null, format, o);
306    }
307
308    @Override
309    public void error(final String format, final Object arg1, final Object arg2) {
310        logger.logIfEnabled(FQCN, Level.ERROR, null, format, arg1, arg2);
311    }
312
313    @Override
314    public void error(final String format, final Object... args) {
315        logger.logIfEnabled(FQCN, Level.ERROR, null, format, args);
316    }
317
318    @Override
319    public void error(final String format, final Throwable t) {
320        logger.logIfEnabled(FQCN, Level.ERROR, null, format, t);
321    }
322
323    @Override
324    public boolean isErrorEnabled() {
325        return logger.isEnabled(Level.ERROR, null, null);
326    }
327
328    @Override
329    public boolean isErrorEnabled(final Marker marker) {
330        return logger.isEnabled(Level.ERROR, getMarker(marker), null);
331    }
332
333    @Override
334    public void error(final Marker marker, final String s) {
335        logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s);
336    }
337
338    @Override
339    public void error(final Marker marker, final String s, final Object o) {
340        logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, o);
341    }
342
343    @Override
344    public void error(final Marker marker, final String s, final Object o, final Object o1) {
345        logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, o, o1);
346    }
347
348    @Override
349    public void error(final Marker marker, final String s, final Object... objects) {
350        logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, objects);
351    }
352
353    @Override
354    public void error(final Marker marker, final String s, final Throwable throwable) {
355        logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, throwable);
356    }
357
358    @Override
359    public void log(final Marker marker, final String fqcn, final int level, final String message, final Object[] params, Throwable throwable) {
360        final Level log4jLevel = getLevel(level);
361        final org.apache.logging.log4j.Marker log4jMarker = getMarker(marker);
362
363        if (!logger.isEnabled(log4jLevel, log4jMarker, message, params)) {
364            return;
365        }
366        final Message msg;
367        if (eventLogger && marker != null && marker.contains(EVENT_MARKER) && converter != null) {
368            msg = converter.convertEvent(message, params, throwable);
369        } else if (params == null) {
370            msg = new SimpleMessage(message);
371        } else {
372            msg = new ParameterizedMessage(message, params, throwable);
373            if (throwable != null) {
374                throwable = msg.getThrowable();
375            }
376        }
377        logger.logMessage(fqcn, log4jLevel, log4jMarker, msg, throwable);
378    }
379
380    private org.apache.logging.log4j.Marker getMarker(final Marker marker) {
381        if (marker == null) {
382            return null;
383        } else if (marker instanceof Log4jMarker) {
384            return ((Log4jMarker) marker).getLog4jMarker();
385        } else {
386            return ((Log4jMarker) markerFactory.getMarker(marker)).getLog4jMarker();
387        }
388    }
389
390    @Override
391    public String getName() {
392        return name;
393    }
394
395    /**
396     * Always treat de-serialization as a full-blown constructor, by validating the final state of
397     * the de-serialized object.
398     */
399    private void readObject(final ObjectInputStream aInputStream) throws ClassNotFoundException, IOException {
400        // always perform the default de-serialization first
401        aInputStream.defaultReadObject();
402        logger = LogManager.getContext().getLogger(name);
403        converter = createConverter();
404        markerFactory = ((Log4jLoggerFactory) org.slf4j.LoggerFactory.getILoggerFactory()).getMarkerFactory();
405    }
406
407    /**
408     * This is the default implementation of writeObject. Customise if necessary.
409     */
410    private void writeObject(final ObjectOutputStream aOutputStream) throws IOException {
411        // perform the default serialization for all non-transient, non-static fields
412        aOutputStream.defaultWriteObject();
413    }
414
415    private static EventDataConverter createConverter() {
416        try {
417            LoaderUtil.loadClass("org.slf4j.ext.EventData");
418            return new EventDataConverter();
419        } catch (final ClassNotFoundException cnfe) {
420            return null;
421        }
422    }
423
424    private static Level getLevel(final int i) {
425        switch (i) {
426        case TRACE_INT:
427            return Level.TRACE;
428        case DEBUG_INT:
429            return Level.DEBUG;
430        case INFO_INT:
431            return Level.INFO;
432        case WARN_INT:
433            return Level.WARN;
434        case ERROR_INT:
435            return Level.ERROR;
436        }
437        return Level.ERROR;
438    }
439}