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