View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.slf4j;
18  
19  import java.io.IOException;
20  import java.io.ObjectInputStream;
21  import java.io.ObjectOutputStream;
22  import java.io.Serializable;
23  
24  import org.apache.logging.log4j.Level;
25  import org.apache.logging.log4j.LogManager;
26  import org.apache.logging.log4j.message.Message;
27  import org.apache.logging.log4j.message.ParameterizedMessage;
28  import org.apache.logging.log4j.message.SimpleMessage;
29  import org.apache.logging.log4j.spi.ExtendedLogger;
30  import org.apache.logging.log4j.util.LoaderUtil;
31  import org.slf4j.Marker;
32  import org.slf4j.MarkerFactory;
33  import org.slf4j.impl.StaticMarkerBinder;
34  import org.slf4j.spi.LocationAwareLogger;
35  
36  /**
37   * SLF4J logger implementation that uses Log4j.
38   */
39  public class Log4jLogger implements LocationAwareLogger, Serializable {
40  
41      public static final String FQCN = Log4jLogger.class.getName();
42  
43      private static final long serialVersionUID = 7869000638091304316L;
44      private static final Marker EVENT_MARKER = MarkerFactory.getMarker("EVENT");
45      private final boolean eventLogger;
46      private transient ExtendedLogger logger;
47      private final String name;
48      private transient EventDataConverter converter;
49  
50      public Log4jLogger(final ExtendedLogger logger, final String name) {
51          this.logger = logger;
52          this.eventLogger = "EventLogger".equals(name);
53          this.name = name;
54          this.converter = createConverter();
55      }
56  
57      @Override
58      public void trace(final String format) {
59          logger.logIfEnabled(FQCN, Level.TRACE, null, format);
60      }
61  
62      @Override
63      public void trace(final String format, final Object o) {
64          logger.logIfEnabled(FQCN, Level.TRACE, null, format, o);
65      }
66  
67      @Override
68      public void trace(final String format, final Object arg1, final Object arg2) {
69          logger.logIfEnabled(FQCN, Level.TRACE, null, format, arg1, arg2);
70      }
71  
72      @Override
73      public void trace(final String format, final Object... args) {
74          logger.logIfEnabled(FQCN, Level.TRACE, null, format, args);
75      }
76  
77      @Override
78      public void trace(final String format, final Throwable t) {
79          logger.logIfEnabled(FQCN, Level.TRACE, null, format, t);
80      }
81  
82      @Override
83      public boolean isTraceEnabled() {
84          return logger.isEnabled(Level.TRACE, null, null);
85      }
86  
87      @Override
88      public boolean isTraceEnabled(final Marker marker) {
89          return logger.isEnabled(Level.TRACE, getMarker(marker), null);
90      }
91  
92      @Override
93      public void trace(final Marker marker, final String s) {
94          logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s);
95      }
96  
97      @Override
98      public void trace(final Marker marker, final String s, final Object o) {
99          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 }