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.security.AccessController; 021import java.security.PrivilegedAction; 022import java.util.logging.Filter; 023import java.util.logging.Level; 024import java.util.logging.LogRecord; 025import java.util.logging.Logger; 026 027import org.apache.logging.log4j.message.Message; 028import org.apache.logging.log4j.message.MessageFactory; 029import org.apache.logging.log4j.spi.ExtendedLogger; 030 031/** 032 * Log4j API implementation of the JUL {@link Logger} class. <strong>Note that this implementation does 033 * <em>not</em> use the {@link java.util.logging.Handler} class.</strong> Instead, logging is delegated to the 034 * underlying Log4j {@link org.apache.logging.log4j.Logger} which may be implemented in one of many different ways. 035 * Consult the documentation for your Log4j Provider for more details. 036 * <p>Note that the methods {@link #getParent()} and {@link #setLevel(java.util.logging.Level)} are not supported by 037 * this implementation. If you need support for these methods, then you'll need to use log4j-core. The 038 * {@link #getParent()} method will not fail (thanks to JUL API limitations), but it won't necessarily be 039 * accurate!</p> 040 * <p>Also note that {@link #setParent(java.util.logging.Logger)} is explicitly unsupported. Parent loggers are 041 * determined using the syntax of the logger name; not through an arbitrary graph of loggers.</p> 042 * 043 * @since 2.1 044 */ 045public class ApiLogger extends Logger { 046 047 private final WrappedLogger logger; 048 private static final String FQCN = ApiLogger.class.getName(); 049 050 ApiLogger(final ExtendedLogger logger) { 051 super(logger.getName(), null); 052 final Level javaLevel = LevelTranslator.toJavaLevel(logger.getLevel()); 053 // "java.util.logging.LoggingPermission" "control" 054 AccessController.doPrivileged((PrivilegedAction<Object>) () -> { 055 ApiLogger.super.setLevel(javaLevel); 056 return null; 057 }); 058 this.logger = new WrappedLogger(logger); 059 } 060 061 @Override 062 public void log(final LogRecord record) { 063 if (isFiltered(record)) { 064 return; 065 } 066 final org.apache.logging.log4j.Level level = LevelTranslator.toLevel(record.getLevel()); 067 final Object[] parameters = record.getParameters(); 068 final MessageFactory messageFactory = logger.getMessageFactory(); 069 final Message message = parameters == null ? 070 messageFactory.newMessage(record.getMessage()) /* LOG4J2-1251: not formatted case */ : 071 messageFactory.newMessage(record.getMessage(), parameters); 072 final Throwable thrown = record.getThrown(); 073 logger.logIfEnabled(FQCN, level, null, message, thrown); 074 } 075 076 // support for Logger.getFilter()/Logger.setFilter() 077 boolean isFiltered(final LogRecord logRecord) { 078 final Filter filter = getFilter(); 079 return filter != null && !filter.isLoggable(logRecord); 080 } 081 082 @Override 083 public boolean isLoggable(final Level level) { 084 return logger.isEnabled(LevelTranslator.toLevel(level)); 085 } 086 087 @Override 088 public String getName() { 089 return logger.getName(); 090 } 091 092 @Override 093 public void setLevel(final Level newLevel) throws SecurityException { 094 throw new UnsupportedOperationException("Cannot set level through log4j-api"); 095 } 096 097 /** 098 * Provides access to {@link Logger#setLevel(java.util.logging.Level)}. This method should only be used by child 099 * 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}