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.slf4j.Marker;
031import org.slf4j.MarkerFactory;
032import org.slf4j.impl.StaticMarkerBinder;
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
049    public Log4jLogger(final ExtendedLogger logger, final String name) {
050        this.logger = logger;
051        this.eventLogger = "EventLogger".equals(name);
052        this.name = name;
053        this.converter = createConverter();
054    }
055
056    @Override
057    public void trace(final String format) {
058        logger.logIfEnabled(FQCN, Level.TRACE, null, format);
059    }
060
061    @Override
062    public void trace(final String format, final Object o) {
063        logger.logIfEnabled(FQCN, Level.TRACE, null, format, o);
064    }
065
066    @Override
067    public void trace(final String format, final Object arg1, final Object arg2) {
068        logger.logIfEnabled(FQCN, Level.TRACE, null, format, arg1, arg2);
069    }
070
071    @Override
072    public void trace(final String format, final Object... args) {
073        logger.logIfEnabled(FQCN, Level.TRACE, null, format, args);
074    }
075
076    @Override
077    public void trace(final String format, final Throwable t) {
078        logger.logIfEnabled(FQCN, Level.TRACE, null, format, t);
079    }
080
081    @Override
082    public boolean isTraceEnabled() {
083        return logger.isEnabled(Level.TRACE, null, null);
084    }
085
086    @Override
087    public boolean isTraceEnabled(final Marker marker) {
088        return logger.isEnabled(Level.TRACE, getMarker(marker), null);
089    }
090
091    @Override
092    public void trace(final Marker marker, final String s) {
093        logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s);
094    }
095
096    @Override
097    public void trace(final Marker marker, final String s, final Object o) {
098        logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, o);
099    }
100
101    @Override
102    public void trace(final Marker marker, final String s, final Object o, final Object o1) {
103        logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, o, o1);
104    }
105
106    @Override
107    public void trace(final Marker marker, final String s, final Object... objects) {
108        logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, objects);
109    }
110
111    @Override
112    public void trace(final Marker marker, final String s, final Throwable throwable) {
113        logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, throwable);
114    }
115
116    @Override
117    public void debug(final String format) {
118        logger.logIfEnabled(FQCN, Level.DEBUG, null, format);
119    }
120
121    @Override
122    public void debug(final String format, final Object o) {
123        logger.logIfEnabled(FQCN, Level.DEBUG, null, format, o);
124    }
125
126    @Override
127    public void debug(final String format, final Object arg1, final Object arg2) {
128        logger.logIfEnabled(FQCN, Level.DEBUG, null, format, arg1, arg2);
129    }
130
131    @Override
132    public void debug(final String format, final Object... args) {
133        logger.logIfEnabled(FQCN, Level.DEBUG, null, format, args);
134    }
135
136    @Override
137    public void debug(final String format, final Throwable t) {
138        logger.logIfEnabled(FQCN, Level.DEBUG, null, format, t);
139    }
140
141    @Override
142    public boolean isDebugEnabled() {
143        return logger.isEnabled(Level.DEBUG, null, null);
144    }
145
146    @Override
147    public boolean isDebugEnabled(final Marker marker) {
148        return logger.isEnabled(Level.DEBUG, getMarker(marker), null);
149    }
150
151    @Override
152    public void debug(final Marker marker, final String s) {
153        logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s);
154    }
155
156    @Override
157    public void debug(final Marker marker, final String s, final Object o) {
158        logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, o);
159    }
160
161    @Override
162    public void debug(final Marker marker, final String s, final Object o, final Object o1) {
163        logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, o, o1);
164    }
165
166    @Override
167    public void debug(final Marker marker, final String s, final Object... objects) {
168        logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, objects);
169    }
170
171    @Override
172    public void debug(final Marker marker, final String s, final Throwable throwable) {
173        logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, throwable);
174    }
175
176    @Override
177    public void info(final String format) {
178        logger.logIfEnabled(FQCN, Level.INFO, null, format);
179    }
180
181    @Override
182    public void info(final String format, final Object o) {
183        logger.logIfEnabled(FQCN, Level.INFO, null, format, o);
184    }
185
186    @Override
187    public void info(final String format, final Object arg1, final Object arg2) {
188        logger.logIfEnabled(FQCN, Level.INFO, null, format, arg1, arg2);
189    }
190
191    @Override
192    public void info(final String format, final Object... args) {
193        logger.logIfEnabled(FQCN, Level.INFO, null, format, args);
194    }
195
196    @Override
197    public void info(final String format, final Throwable t) {
198        logger.logIfEnabled(FQCN, Level.INFO, null, format, t);
199    }
200
201    @Override
202    public boolean isInfoEnabled() {
203        return logger.isEnabled(Level.INFO, null, null);
204    }
205
206    @Override
207    public boolean isInfoEnabled(final Marker marker) {
208        return logger.isEnabled(Level.INFO, getMarker(marker), null);
209    }
210
211    @Override
212    public void info(final Marker marker, final String s) {
213        logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s);
214    }
215
216    @Override
217    public void info(final Marker marker, final String s, final Object o) {
218        logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, o);
219    }
220
221    @Override
222    public void info(final Marker marker, final String s, final Object o, final Object o1) {
223        logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, o, o1);
224    }
225
226    @Override
227    public void info(final Marker marker, final String s, final Object... objects) {
228        logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, objects);
229    }
230
231    @Override
232    public void info(final Marker marker, final String s, final Throwable throwable) {
233        logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, throwable);
234    }
235
236    @Override
237    public void warn(final String format) {
238        logger.logIfEnabled(FQCN, Level.WARN, null, format);
239    }
240
241    @Override
242    public void warn(final String format, final Object o) {
243        logger.logIfEnabled(FQCN, Level.WARN, null, format, o);
244    }
245
246    @Override
247    public void warn(final String format, final Object arg1, final Object arg2) {
248        logger.logIfEnabled(FQCN, Level.WARN, null, format, arg1, arg2);
249    }
250
251    @Override
252    public void warn(final String format, final Object... args) {
253        logger.logIfEnabled(FQCN, Level.WARN, null, format, args);
254    }
255
256    @Override
257    public void warn(final String format, final Throwable t) {
258        logger.logIfEnabled(FQCN, Level.WARN, null, format, t);
259    }
260
261    @Override
262    public boolean isWarnEnabled() {
263        return logger.isEnabled(Level.WARN, null, null);
264    }
265
266    @Override
267    public boolean isWarnEnabled(final Marker marker) {
268        return logger.isEnabled(Level.WARN, getMarker(marker), null);
269    }
270
271    @Override
272    public void warn(final Marker marker, final String s) {
273        logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s);
274    }
275
276    @Override
277    public void warn(final Marker marker, final String s, final Object o) {
278        logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, o);
279    }
280
281    @Override
282    public void warn(final Marker marker, final String s, final Object o, final Object o1) {
283        logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, o, o1);
284    }
285
286    @Override
287    public void warn(final Marker marker, final String s, final Object... objects) {
288        logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, objects);
289    }
290
291    @Override
292    public void warn(final Marker marker, final String s, final Throwable throwable) {
293        logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, throwable);
294    }
295
296    @Override
297    public void error(final String format) {
298        logger.logIfEnabled(FQCN, Level.ERROR, null, format);
299    }
300
301    @Override
302    public void error(final String format, final Object o) {
303        logger.logIfEnabled(FQCN, Level.ERROR, null, format, o);
304    }
305
306    @Override
307    public void error(final String format, final Object arg1, final Object arg2) {
308        logger.logIfEnabled(FQCN, Level.ERROR, null, format, arg1, arg2);
309    }
310
311    @Override
312    public void error(final String format, final Object... args) {
313        logger.logIfEnabled(FQCN, Level.ERROR, null, format, args);
314    }
315
316    @Override
317    public void error(final String format, final Throwable t) {
318        logger.logIfEnabled(FQCN, Level.ERROR, null, format, t);
319    }
320
321    @Override
322    public boolean isErrorEnabled() {
323        return logger.isEnabled(Level.ERROR, null, null);
324    }
325
326    @Override
327    public boolean isErrorEnabled(final Marker marker) {
328        return logger.isEnabled(Level.ERROR, getMarker(marker), null);
329    }
330
331    @Override
332    public void error(final Marker marker, final String s) {
333        logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s);
334    }
335
336    @Override
337    public void error(final Marker marker, final String s, final Object o) {
338        logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, o);
339    }
340
341    @Override
342    public void error(final Marker marker, final String s, final Object o, final Object o1) {
343        logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, o, o1);
344    }
345
346    @Override
347    public void error(final Marker marker, final String s, final Object... objects) {
348        logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, objects);
349    }
350
351    @Override
352    public void error(final Marker marker, final String s, final Throwable throwable) {
353        logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, throwable);
354    }
355
356    @Override
357    public void log(final Marker marker, final String fqcn, final int level, final String message, final Object[] params, Throwable throwable) {
358        final Level log4jLevel = getLevel(level);
359        final org.apache.logging.log4j.Marker log4jMarker = getMarker(marker);
360
361        if (!logger.isEnabled(log4jLevel, log4jMarker, message, params)) {
362            return;
363        }
364        final Message msg;
365        if (eventLogger && marker != null && marker.contains(EVENT_MARKER) && converter != null) {
366            msg = converter.convertEvent(message, params, throwable);
367        } else if (params == null) {
368            msg = new SimpleMessage(message);
369        } else {
370            msg = new ParameterizedMessage(message, params, throwable);
371            if (throwable != null) {
372                throwable = msg.getThrowable();
373            }
374        }
375        logger.logMessage(fqcn, log4jLevel, log4jMarker, msg, throwable);
376    }
377
378    private static org.apache.logging.log4j.Marker getMarker(final Marker marker) {
379        if (marker == null) {
380            return null;
381        } else if (marker instanceof Log4jMarker) {
382            return ((Log4jMarker) marker).getLog4jMarker();
383        } else {
384            final Log4jMarkerFactory factory = (Log4jMarkerFactory) StaticMarkerBinder.SINGLETON.getMarkerFactory();
385            return ((Log4jMarker) factory.getMarker(marker)).getLog4jMarker();
386        }
387    }
388
389    @Override
390    public String getName() {
391        return name;
392    }
393
394    /**
395     * Always treat de-serialization as a full-blown constructor, by validating the final state of
396     * the de-serialized object.
397     */
398    private void readObject(final ObjectInputStream aInputStream) throws ClassNotFoundException, IOException {
399        // always perform the default de-serialization first
400        aInputStream.defaultReadObject();
401        logger = LogManager.getContext().getLogger(name);
402        converter = createConverter();
403    }
404
405    /**
406     * This is the default implementation of writeObject. Customise if necessary.
407     */
408    private void writeObject(final ObjectOutputStream aOutputStream) throws IOException {
409        // perform the default serialization for all non-transient, non-static fields
410        aOutputStream.defaultWriteObject();
411    }
412
413    private static EventDataConverter createConverter() {
414        try {
415            Class.forName("org.slf4j.ext.EventData");
416            return new EventDataConverter();
417        } catch (final ClassNotFoundException cnfe) {
418            return null;
419        }
420    }
421
422    private static Level getLevel(final int i) {
423        switch (i) {
424        case TRACE_INT:
425            return Level.TRACE;
426        case DEBUG_INT:
427            return Level.DEBUG;
428        case INFO_INT:
429            return Level.INFO;
430        case WARN_INT:
431            return Level.WARN;
432        case ERROR_INT:
433            return Level.ERROR;
434        }
435        return Level.ERROR;
436    }
437}