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  
18  package org.apache.logging.log4j.jul;
19  
20  import java.security.AccessController;
21  import java.security.PrivilegedAction;
22  import java.util.logging.Filter;
23  import java.util.logging.Level;
24  import java.util.logging.LogRecord;
25  import java.util.logging.Logger;
26  
27  import org.apache.logging.log4j.message.Message;
28  import org.apache.logging.log4j.message.MessageFactory;
29  import org.apache.logging.log4j.spi.ExtendedLogger;
30  
31  /**
32   * Log4j API implementation of the JUL {@link Logger} class. <strong>Note that this implementation does
33   * <em>not</em> use the {@link java.util.logging.Handler} class.</strong> Instead, logging is delegated to the
34   * underlying Log4j {@link org.apache.logging.log4j.Logger} which may be implemented in one of many different ways.
35   * Consult the documentation for your Log4j Provider for more details.
36   * <p>Note that the methods {@link #getParent()} and {@link #setLevel(java.util.logging.Level)} are not supported by
37   * this implementation. If you need support for these methods, then you'll need to use log4j-core. The
38   * {@link #getParent()} method will not fail (thanks to JUL API limitations), but it won't necessarily be
39   * accurate!</p>
40   * <p>Also note that {@link #setParent(java.util.logging.Logger)} is explicitly unsupported. Parent loggers are
41   * determined using the syntax of the logger name; not through an arbitrary graph of loggers.</p>
42   *
43   * @since 2.1
44   */
45  public class ApiLogger extends Logger {
46  
47      private final WrappedLogger logger;
48      private static final String FQCN = ApiLogger.class.getName();
49  
50      ApiLogger(final ExtendedLogger logger) {
51          super(logger.getName(), null);
52          final Level javaLevel = LevelTranslator.toJavaLevel(logger.getLevel());
53          // "java.util.logging.LoggingPermission" "control"
54          AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
55              ApiLogger.super.setLevel(javaLevel);
56              return null;
57          });
58          this.logger = new WrappedLogger(logger);
59      }
60  
61      @Override
62      public void log(final LogRecord record) {
63          if (isFiltered(record)) {
64              return;
65          }
66          final org.apache.logging.log4j.Level level = LevelTranslator.toLevel(record.getLevel());
67          final Object[] parameters = record.getParameters();
68          final MessageFactory messageFactory = logger.getMessageFactory();
69          final Message message = parameters == null ?
70              messageFactory.newMessage(record.getMessage()) /* LOG4J2-1251: not formatted case */ :
71              messageFactory.newMessage(record.getMessage(), parameters);
72          final Throwable thrown = record.getThrown();
73          logger.logIfEnabled(FQCN, level, null, message, thrown);
74      }
75  
76      // support for Logger.getFilter()/Logger.setFilter()
77      boolean isFiltered(final LogRecord logRecord) {
78          final Filter filter = getFilter();
79          return filter != null && !filter.isLoggable(logRecord);
80      }
81  
82      @Override
83      public boolean isLoggable(final Level level) {
84          return logger.isEnabled(LevelTranslator.toLevel(level));
85      }
86  
87      @Override
88      public String getName() {
89          return logger.getName();
90      }
91  
92      @Override
93      public void setLevel(final Level newLevel) throws SecurityException {
94          throw new UnsupportedOperationException("Cannot set level through log4j-api");
95      }
96  
97      /**
98       * Provides access to {@link Logger#setLevel(java.util.logging.Level)}. This method should only be used by child
99       * classes.
100      *
101      * @see Logger#setLevel(java.util.logging.Level)
102      */
103     protected void doSetLevel(final Level newLevel) throws SecurityException {
104         super.setLevel(newLevel);
105     }
106 
107     /**
108      * Unsupported operation.
109      *
110      * @throws UnsupportedOperationException always
111      */
112     @Override
113     public void setParent(final Logger parent) {
114         throw new UnsupportedOperationException("Cannot set parent logger");
115     }
116 
117     @Override
118     public void log(final Level level, final String msg) {
119         if (getFilter() == null) {
120             logger.log(LevelTranslator.toLevel(level), msg);
121         } else {
122             super.log(level, msg);
123         }
124     }
125 
126     @Override
127     public void log(final Level level, final String msg, final Object param1) {
128         if (getFilter() == null) {
129             logger.log(LevelTranslator.toLevel(level), msg, param1);
130         } else {
131             super.log(level, msg, param1);
132         }
133     }
134 
135     @Override
136     public void log(final Level level, final String msg, final Object[] params) {
137         if (getFilter() == null) {
138             logger.log(LevelTranslator.toLevel(level), msg, params);
139         } else {
140             super.log(level, msg, params);
141         }
142     }
143 
144     @Override
145     public void log(final Level level, final String msg, final Throwable thrown) {
146         if (getFilter() == null) {
147             logger.log(LevelTranslator.toLevel(level), msg, thrown);
148         } else {
149             super.log(level, msg, thrown);
150         }
151     }
152 
153     @Override
154     public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg) {
155         log(level, msg);
156     }
157 
158     @Override
159     public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg,
160                      final Object param1) {
161         log(level, msg, param1);
162     }
163 
164     @Override
165     public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg,
166                      final Object[] params) {
167         log(level, msg, params);
168     }
169 
170     @Override
171     public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg,
172                      final Throwable thrown) {
173         log(level, msg, thrown);
174     }
175 
176     @Override
177     public void logrb(final Level level, final String sourceClass, final String sourceMethod, final String bundleName,
178                       final String msg) {
179         log(level, msg);
180     }
181 
182     @Override
183     public void logrb(final Level level, final String sourceClass, final String sourceMethod, final String bundleName,
184                       final String msg, final Object param1) {
185         log(level, msg, param1);
186     }
187 
188     @Override
189     public void logrb(final Level level, final String sourceClass, final String sourceMethod, final String bundleName,
190                       final String msg, final Object[] params) {
191         log(level, msg, params);
192     }
193 
194     @Override
195     public void logrb(final Level level, final String sourceClass, final String sourceMethod, final String bundleName,
196                       final String msg, final Throwable thrown) {
197         log(level, msg, thrown);
198     }
199 
200     @Override
201     public void entering(final String sourceClass, final String sourceMethod) {
202         logger.entry();
203     }
204 
205     @Override
206     public void entering(final String sourceClass, final String sourceMethod, final Object param1) {
207         logger.entry(param1);
208     }
209 
210     @Override
211     public void entering(final String sourceClass, final String sourceMethod, final Object[] params) {
212         logger.entry(params);
213     }
214 
215     @Override
216     public void exiting(final String sourceClass, final String sourceMethod) {
217         logger.exit();
218     }
219 
220     @Override
221     public void exiting(final String sourceClass, final String sourceMethod, final Object result) {
222         logger.exit(result);
223     }
224 
225     @Override
226     public void throwing(final String sourceClass, final String sourceMethod, final Throwable thrown) {
227         logger.throwing(thrown);
228     }
229 
230     @Override
231     public void severe(final String msg) {
232         if (getFilter() == null) {
233             logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.ERROR, null, msg);
234         } else {
235             super.severe(msg);
236         }
237     }
238 
239     @Override
240     public void warning(final String msg) {
241         if (getFilter() == null) {
242             logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.WARN, null, msg);
243         } else {
244             super.warning(msg);
245         }
246     }
247 
248     @Override
249     public void info(final String msg) {
250         if (getFilter() == null) {
251             logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.INFO, null, msg);
252         } else {
253             super.info(msg);
254         }
255     }
256 
257     @Override
258     public void config(final String msg) {
259         if (getFilter() == null) {
260             logger.logIfEnabled(FQCN, LevelTranslator.CONFIG, null, msg);
261         } else {
262             super.config(msg);
263         }
264     }
265 
266     @Override
267     public void fine(final String msg) {
268         if (getFilter() == null) {
269             logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.DEBUG, null, msg);
270         } else {
271             super.fine(msg);
272         }
273     }
274 
275     @Override
276     public void finer(final String msg) {
277         if (getFilter() == null) {
278             logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.TRACE, null, msg);
279         } else {
280             super.finer(msg);
281         }
282     }
283 
284     @Override
285     public void finest(final String msg) {
286         if (getFilter() == null) {
287             logger.logIfEnabled(FQCN, LevelTranslator.FINEST, null, msg);
288         } else {
289             super.finest(msg);
290         }
291     }
292 }