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 */
017
018package org.apache.logging.log4j.jul;
019
020import java.util.logging.Filter;
021import java.util.logging.Level;
022import java.util.logging.LogRecord;
023import java.util.logging.Logger;
024
025import org.apache.logging.log4j.message.Message;
026import org.apache.logging.log4j.message.MessageFactory;
027import org.apache.logging.log4j.spi.ExtendedLogger;
028
029/**
030 * Log4j API implementation of the JUL {@link Logger} class. <strong>Note that this implementation does
031 * <em>not</em> use the {@link java.util.logging.Handler} class.</strong> Instead, logging is delegated to the
032 * underlying Log4j {@link org.apache.logging.log4j.Logger} which may be implemented in one of many different ways.
033 * Consult the documentation for your Log4j Provider for more details.
034 * <p>Note that the methods {@link #getParent()} and {@link #setLevel(java.util.logging.Level)} are not supported by
035 * this implementation. If you need support for these methods, then you'll need to use log4j-core. The
036 * {@link #getParent()} method will not fail (thanks to JUL API limitations), but it won't necessarily be
037 * accurate!</p>
038 * <p>Also note that {@link #setParent(java.util.logging.Logger)} is explicitly unsupported. Parent loggers are
039 * determined using the syntax of the logger name; not through an arbitrary graph of loggers.</p>
040 *
041 * @since 2.1
042 */
043public class ApiLogger extends Logger {
044
045    private final WrappedLogger logger;
046    private static final String FQCN = ApiLogger.class.getName();
047
048    ApiLogger(final ExtendedLogger logger) {
049        super(logger.getName(), null);
050        super.setLevel(LevelTranslator.toJavaLevel(logger.getLevel()));
051        this.logger = new WrappedLogger(logger);
052    }
053
054    @Override
055    public void log(final LogRecord record) {
056        if (isFiltered(record)) {
057            return;
058        }
059        final org.apache.logging.log4j.Level level = LevelTranslator.toLevel(record.getLevel());
060        final Object[] parameters = record.getParameters();
061        final MessageFactory messageFactory = logger.getMessageFactory();
062        final Message message = parameters == null ?
063            messageFactory.newMessage(record.getMessage()) /* LOG4J2-1251: not formatted case */ :
064            messageFactory.newMessage(record.getMessage(), parameters);
065        final Throwable thrown = record.getThrown();
066        logger.logIfEnabled(FQCN, level, null, message, thrown);
067    }
068
069    // support for Logger.getFilter()/Logger.setFilter()
070    boolean isFiltered(final LogRecord logRecord) {
071        final Filter filter = getFilter();
072        return filter != null && !filter.isLoggable(logRecord);
073    }
074
075    @Override
076    public boolean isLoggable(final Level level) {
077        return logger.isEnabled(LevelTranslator.toLevel(level));
078    }
079
080    @Override
081    public String getName() {
082        return logger.getName();
083    }
084
085    @Override
086    public void setLevel(final Level newLevel) throws SecurityException {
087        throw new UnsupportedOperationException("Cannot set level through log4j-api");
088    }
089
090    /**
091     * Provides access to {@link Logger#setLevel(java.util.logging.Level)}. This method should only be used by child
092     * classes.
093     *
094     * @see Logger#setLevel(java.util.logging.Level)
095     */
096    protected void doSetLevel(final Level newLevel) throws SecurityException {
097        super.setLevel(newLevel);
098    }
099
100    /**
101     * Unsupported operation.
102     *
103     * @throws UnsupportedOperationException always
104     */
105    @Override
106    public void setParent(final Logger parent) {
107        throw new UnsupportedOperationException("Cannot set parent logger");
108    }
109
110    @Override
111    public void log(final Level level, final String msg) {
112        logger.log(LevelTranslator.toLevel(level), msg);
113    }
114
115    @Override
116    public void log(final Level level, final String msg, final Object param1) {
117        logger.log(LevelTranslator.toLevel(level), msg, param1);
118    }
119
120    @Override
121    public void log(final Level level, final String msg, final Object[] params) {
122        logger.log(LevelTranslator.toLevel(level), msg, params);
123    }
124
125    @Override
126    public void log(final Level level, final String msg, final Throwable thrown) {
127        logger.log(LevelTranslator.toLevel(level), msg, thrown);
128    }
129
130    @Override
131    public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg) {
132        log(level, msg);
133    }
134
135    @Override
136    public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg,
137                     final Object param1) {
138        log(level, msg, param1);
139    }
140
141    @Override
142    public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg,
143                     final Object[] params) {
144        log(level, msg, params);
145    }
146
147    @Override
148    public void logp(final Level level, final String sourceClass, final String sourceMethod, final String msg,
149                     final Throwable thrown) {
150        log(level, msg, thrown);
151    }
152
153    @Override
154    public void logrb(final Level level, final String sourceClass, final String sourceMethod, final String bundleName,
155                      final String msg) {
156        log(level, msg);
157    }
158
159    @Override
160    public void logrb(final Level level, final String sourceClass, final String sourceMethod, final String bundleName,
161                      final String msg, final Object param1) {
162        log(level, msg, param1);
163    }
164
165    @Override
166    public void logrb(final Level level, final String sourceClass, final String sourceMethod, final String bundleName,
167                      final String msg, final Object[] params) {
168        log(level, msg, params);
169    }
170
171    @Override
172    public void logrb(final Level level, final String sourceClass, final String sourceMethod, final String bundleName,
173                      final String msg, final Throwable thrown) {
174        log(level, msg, thrown);
175    }
176
177    @Override
178    public void entering(final String sourceClass, final String sourceMethod) {
179        logger.entry();
180    }
181
182    @Override
183    public void entering(final String sourceClass, final String sourceMethod, final Object param1) {
184        logger.entry(param1);
185    }
186
187    @Override
188    public void entering(final String sourceClass, final String sourceMethod, final Object[] params) {
189        logger.entry(params);
190    }
191
192    @Override
193    public void exiting(final String sourceClass, final String sourceMethod) {
194        logger.exit();
195    }
196
197    @Override
198    public void exiting(final String sourceClass, final String sourceMethod, final Object result) {
199        logger.exit(result);
200    }
201
202    @Override
203    public void throwing(final String sourceClass, final String sourceMethod, final Throwable thrown) {
204        logger.throwing(thrown);
205    }
206
207    @Override
208    public void severe(final String msg) {
209        logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.ERROR, null, msg);
210    }
211
212    @Override
213    public void warning(final String msg) {
214        logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.WARN, null, msg);
215    }
216
217    @Override
218    public void info(final String msg) {
219        logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.INFO, null, msg);
220    }
221
222    @Override
223    public void config(final String msg) {
224        logger.logIfEnabled(FQCN, LevelTranslator.CONFIG, null, msg);
225    }
226
227    @Override
228    public void fine(final String msg) {
229        logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.DEBUG, null, msg);
230    }
231
232    @Override
233    public void finer(final String msg) {
234        logger.logIfEnabled(FQCN, org.apache.logging.log4j.Level.TRACE, null, msg);
235    }
236
237    @Override
238    public void finest(final String msg) {
239        logger.logIfEnabled(FQCN, LevelTranslator.FINEST, null, msg);
240    }
241}