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.spi.LocationAwareLogger;
34  
35  /**
36   * SLF4J logger implementation that uses Log4j.
37   */
38  public class Log4jLogger implements LocationAwareLogger, Serializable {
39  
40      public static final String FQCN = Log4jLogger.class.getName();
41  
42      private static final long serialVersionUID = 7869000638091304316L;
43      private static final Marker EVENT_MARKER = MarkerFactory.getMarker("EVENT");
44      private final boolean eventLogger;
45      private transient ExtendedLogger logger;
46      private final String name;
47      private transient EventDataConverter converter;
48      private transient Log4jMarkerFactory markerFactory;
49  
50      public Log4jLogger(final Log4jMarkerFactory markerFactory, final ExtendedLogger logger, final String name) {
51          this.markerFactory = markerFactory;
52          this.logger = logger;
53          this.eventLogger = "EventLogger".equals(name);
54          this.name = name;
55          this.converter = createConverter();
56      }
57  
58      @Override
59      public void trace(final String format) {
60          logger.logIfEnabled(FQCN, Level.TRACE, null, format);
61      }
62  
63      @Override
64      public void trace(final String format, final Object o) {
65          logger.logIfEnabled(FQCN, Level.TRACE, null, format, o);
66      }
67  
68      @Override
69      public void trace(final String format, final Object arg1, final Object arg2) {
70          logger.logIfEnabled(FQCN, Level.TRACE, null, format, arg1, arg2);
71      }
72  
73      @Override
74      public void trace(final String format, final Object... args) {
75          logger.logIfEnabled(FQCN, Level.TRACE, null, format, args);
76      }
77  
78      @Override
79      public void trace(final String format, final Throwable t) {
80          logger.logIfEnabled(FQCN, Level.TRACE, null, format, t);
81      }
82  
83      @Override
84      public boolean isTraceEnabled() {
85          return logger.isEnabled(Level.TRACE, null, null);
86      }
87  
88      @Override
89      public boolean isTraceEnabled(final Marker marker) {
90          return logger.isEnabled(Level.TRACE, getMarker(marker), null);
91      }
92  
93      @Override
94      public void trace(final Marker marker, final String s) {
95          logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s);
96      }
97  
98      @Override
99      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 }