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