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(new PrivilegedAction<Object>() {
55              @Override
56              public Object run() {
57                  ApiLogger.super.setLevel(javaLevel);
58                  return null;
59              }
60          });
61          this.logger = new WrappedLogger(logger);
62      }
63  
64      @Override
65      public void log(final LogRecord record) {
66          if (isFiltered(record)) {
67              return;
68          }
69          final org.apache.logging.log4j.Level level = LevelTranslator.toLevel(record.getLevel());
70          final Object[] parameters = record.getParameters();
71          final MessageFactory messageFactory = logger.getMessageFactory();
72          final Message message = parameters == null ?
73              messageFactory.newMessage(record.getMessage()) /* LOG4J2-1251: not formatted case */ :
74              messageFactory.newMessage(record.getMessage(), parameters);
75          final Throwable thrown = record.getThrown();
76          logger.logIfEnabled(FQCN, level, null, message, thrown);
77      }
78  
79      // support for Logger.getFilter()/Logger.setFilter()
80      boolean isFiltered(final LogRecord logRecord) {
81          final Filter filter = getFilter();
82          return filter != null && !filter.isLoggable(logRecord);
83      }
84  
85      @Override
86      public boolean isLoggable(final Level level) {
87          return logger.isEnabled(LevelTranslator.toLevel(level));
88      }
89  
90      @Override
91      public String getName() {
92          return logger.getName();
93      }
94  
95      @Override
96      public void setLevel(final Level newLevel) throws SecurityException {
97          throw new UnsupportedOperationException("Cannot set level through log4j-api");
98      }
99  
100     /**
101      * Provides access to {@link Logger#setLevel(java.util.logging.Level)}. This method should only be used by child
102      * classes.
103      *
104      * @see Logger#setLevel(java.util.logging.Level)
105      */
106     protected void doSetLevel(final Level newLevel) throws SecurityException {
107         super.setLevel(newLevel);
108     }
109 
110     /**
111      * Unsupported operation.
112      *
113      * @throws UnsupportedOperationException always
114      */
115     @Override
116     public void setParent(final Logger parent) {
117         throw new UnsupportedOperationException("Cannot set parent logger");
118     }
119 
120     @Override
121     public void log(final Level level, final String msg) {
122         logger.log(LevelTranslator.toLevel(level), msg);
123     }
124 
125     @Override
126     public void log(final Level level, final String msg, final Object param1) {
127         logger.log(LevelTranslator.toLevel(level), msg, param1);
128     }
129 
130     @Override
131     public void log(final Level level, final String msg, final Object[] params) {
132         logger.log(LevelTranslator.toLevel(level), msg, params);
133     }
134 
135     @Override
136     public void log(final Level level, final String msg, final Throwable thrown) {
137         logger.log(LevelTranslator.toLevel(level), msg, thrown);
138     }
139 
140     @Override
141     public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg) {
142         log(level, msg);
143     }
144 
145     @Override
146     public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg,
147                      final Object param1) {
148         log(level, msg, param1);
149     }
150 
151     @Override
152     public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg,
153                      final Object[] params) {
154         log(level, msg, params);
155     }
156 
157     @Override
158     public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg,
159                      final Throwable thrown) {
160         log(level, msg, thrown);
161     }
162 
163     @Override
164     public void logrb(final Level level, final String sourceClass, final String sourceMethod, final String bundleName,
165                       final String msg) {
166         log(level, msg);
167     }
168 
169     @Override
170     public void logrb(final Level level, final String sourceClass, final String sourceMethod, final String bundleName,
171                       final String msg, final Object param1) {
172         log(level, msg, param1);
173     }
174 
175     @Override
176     public void logrb(final Level level, final String sourceClass, final String sourceMethod, final String bundleName,
177                       final String msg, final Object[] params) {
178         log(level, msg, params);
179     }
180 
181     @Override
182     public void logrb(final Level level, final String sourceClass, final String sourceMethod, final String bundleName,
183                       final String msg, final Throwable thrown) {
184         log(level, msg, thrown);
185     }
186 
187     @Override
188     public void entering(final String sourceClass, final String sourceMethod) {
189         logger.entry();
190     }
191 
192     @Override
193     public void entering(final String sourceClass, final String sourceMethod, final Object param1) {
194         logger.entry(param1);
195     }
196 
197     @Override
198     public void entering(final String sourceClass, final String sourceMethod, final Object[] params) {
199         logger.entry(params);
200     }
201 
202     @Override
203     public void exiting(final String sourceClass, final String sourceMethod) {
204         logger.exit();
205     }
206 
207     @Override
208     public void exiting(final String sourceClass, final String sourceMethod, final Object result) {
209         logger.exit(result);
210     }
211 
212     @Override
213     public void throwing(final String sourceClass, final String sourceMethod, final Throwable thrown) {
214         logger.throwing(thrown);
215     }
216 
217     @Override
218     public void severe(final String msg) {
219         logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.ERROR, null, msg);
220     }
221 
222     @Override
223     public void warning(final String msg) {
224         logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.WARN, null, msg);
225     }
226 
227     @Override
228     public void info(final String msg) {
229         logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.INFO, null, msg);
230     }
231 
232     @Override
233     public void config(final String msg) {
234         logger.logIfEnabled(FQCN, LevelTranslator.CONFIG, null, msg);
235     }
236 
237     @Override
238     public void fine(final String msg) {
239         logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.DEBUG, null, msg);
240     }
241 
242     @Override
243     public void finer(final String msg) {
244         logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.TRACE, null, msg);
245     }
246 
247     @Override
248     public void finest(final String msg) {
249         logger.logIfEnabled(FQCN, LevelTranslator.FINEST, null, msg);
250     }
251 }