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 package org.apache.log4j; 018 019 import org.apache.log4j.helpers.NullEnumeration; 020 import org.apache.log4j.spi.LoggerFactory; 021 import org.apache.log4j.spi.LoggingEvent; 022 import org.apache.logging.log4j.core.LoggerContext; 023 import org.apache.logging.log4j.core.helpers.NameUtil; 024 import org.apache.logging.log4j.message.LocalizedMessage; 025 import org.apache.logging.log4j.message.Message; 026 import org.apache.logging.log4j.message.ObjectMessage; 027 028 import java.util.Enumeration; 029 import java.util.Map; 030 import java.util.ResourceBundle; 031 import java.util.WeakHashMap; 032 import java.util.concurrent.ConcurrentHashMap; 033 import java.util.concurrent.ConcurrentMap; 034 035 036 /** 037 * Implementation of the Category class for compatibility, despite it having been deprecated a long, long time ago. 038 */ 039 public class Category { 040 041 private static LoggerFactory loggerFactory = new PrivateFactory(); 042 043 private static final Map<LoggerContext, ConcurrentMap<String, Logger>> CONTEXT_MAP = 044 new WeakHashMap<LoggerContext, ConcurrentMap<String, Logger>>(); 045 046 private static final String FQCN = Category.class.getName(); 047 048 /** 049 * Resource bundle for localized messages. 050 */ 051 protected ResourceBundle bundle = null; 052 053 private final org.apache.logging.log4j.core.Logger logger; 054 055 /** 056 * Constructor used by Logger to specify a LoggerContext. 057 * @param context The LoggerContext. 058 * @param name The name of the Logger. 059 */ 060 protected Category(final LoggerContext context, final String name) { 061 this.logger = context.getLogger(name); 062 } 063 064 /** 065 * Constructor exposed by Log4j 1.2. 066 * @param name The name of the Logger. 067 */ 068 protected Category(final String name) { 069 this((LoggerContext) PrivateManager.getContext(), name); 070 } 071 072 private Category(final org.apache.logging.log4j.core.Logger logger) { 073 this.logger = logger; 074 } 075 076 public static Category getInstance(final String name) { 077 return getInstance((LoggerContext) PrivateManager.getContext(), name, loggerFactory); 078 } 079 080 static Category getInstance(final LoggerContext context, final String name) { 081 return getInstance(context, name, loggerFactory); 082 } 083 084 static Category getInstance(final LoggerContext context, final String name, final LoggerFactory factory) { 085 final ConcurrentMap<String, Logger> loggers = getLoggersMap(context); 086 Logger logger = loggers.get(name); 087 if (logger != null) { 088 return logger; 089 } 090 logger = factory.makeNewLoggerInstance(context, name); 091 final Logger prev = loggers.putIfAbsent(name, logger); 092 return prev == null ? logger : prev; 093 } 094 095 public static Category getInstance(final Class clazz) { 096 return getInstance(clazz.getName()); 097 } 098 099 static Category getInstance(final LoggerContext context, final Class clazz) { 100 return getInstance(context, clazz.getName()); 101 } 102 103 public final String getName() { 104 return logger.getName(); 105 } 106 107 org.apache.logging.log4j.core.Logger getLogger() { 108 return logger; 109 } 110 111 public final Category getParent() { 112 final org.apache.logging.log4j.core.Logger parent = logger.getParent(); 113 if (parent == null) { 114 return null; 115 } 116 final ConcurrentMap<String, Logger> loggers = getLoggersMap(logger.getContext()); 117 final Logger l = loggers.get(parent.getName()); 118 return l == null ? new Category(parent) : l; 119 } 120 121 public static Category getRoot() { 122 return getInstance(""); 123 } 124 125 126 static Category getRoot(final LoggerContext context) { 127 return getInstance(context, ""); 128 } 129 130 private static ConcurrentMap<String, Logger> getLoggersMap(final LoggerContext context) { 131 synchronized (CONTEXT_MAP) { 132 ConcurrentMap<String, Logger> map = CONTEXT_MAP.get(context); 133 if (map == null) { 134 map = new ConcurrentHashMap<String, Logger>(); 135 CONTEXT_MAP.put(context, map); 136 } 137 return map; 138 } 139 } 140 141 /** 142 Returns all the currently defined categories in the default 143 hierarchy as an {@link java.util.Enumeration Enumeration}. 144 145 <p>The root category is <em>not</em> included in the returned 146 {@link Enumeration}. 147 @return and Enumeration of the Categories. 148 149 @deprecated Please use {@link LogManager#getCurrentLoggers()} instead. 150 */ 151 @Deprecated 152 public static Enumeration getCurrentCategories() { 153 return LogManager.getCurrentLoggers(); 154 } 155 156 public final Level getEffectiveLevel() { 157 final org.apache.logging.log4j.Level level = logger.getLevel(); 158 159 switch (level) { 160 case TRACE: 161 return Level.TRACE; 162 case DEBUG: 163 return Level.DEBUG; 164 case INFO: 165 return Level.INFO; 166 case WARN: 167 return Level.WARN; 168 default: 169 return Level.ERROR; 170 } 171 } 172 173 public final Priority getChainedPriority() { 174 return getEffectiveLevel(); 175 } 176 177 public final Level getLevel() { 178 return getEffectiveLevel(); 179 } 180 181 public void setLevel(final Level level) { 182 logger.setLevel(org.apache.logging.log4j.Level.toLevel(level.levelStr)); 183 } 184 185 public final Level getPriority() { 186 return getEffectiveLevel(); 187 } 188 189 public void setPriority(final Priority priority) { 190 logger.setLevel(org.apache.logging.log4j.Level.toLevel(priority.levelStr)); 191 } 192 193 public void debug(final Object message) { 194 maybeLog(FQCN, org.apache.logging.log4j.Level.DEBUG, message, null); 195 } 196 197 public void debug(final Object message, final Throwable t) { 198 maybeLog(FQCN, org.apache.logging.log4j.Level.DEBUG, message, t); 199 } 200 201 public boolean isDebugEnabled() { 202 return logger.isDebugEnabled(); 203 } 204 205 public void error(final Object message) { 206 maybeLog(FQCN, org.apache.logging.log4j.Level.ERROR, message, null); 207 } 208 209 public void error(final Object message, final Throwable t) { 210 maybeLog(FQCN, org.apache.logging.log4j.Level.ERROR, message, t); 211 } 212 213 public boolean isErrorEnabled() { 214 return logger.isErrorEnabled(); 215 } 216 217 public void warn(final Object message) { 218 maybeLog(FQCN, org.apache.logging.log4j.Level.WARN, message, null); 219 } 220 221 public void warn(final Object message, final Throwable t) { 222 maybeLog(FQCN, org.apache.logging.log4j.Level.WARN, message, t); 223 } 224 225 public boolean isWarnEnabled() { 226 return logger.isWarnEnabled(); 227 } 228 229 public void fatal(final Object message) { 230 maybeLog(FQCN, org.apache.logging.log4j.Level.FATAL, message, null); 231 } 232 233 public void fatal(final Object message, final Throwable t) { 234 maybeLog(FQCN, org.apache.logging.log4j.Level.FATAL, message, t); 235 } 236 237 public boolean isFatalEnabled() { 238 return logger.isFatalEnabled(); 239 } 240 241 public void info(final Object message) { 242 maybeLog(FQCN, org.apache.logging.log4j.Level.INFO, message, null); 243 } 244 245 public void info(final Object message, final Throwable t) { 246 maybeLog(FQCN, org.apache.logging.log4j.Level.INFO, message, t); 247 } 248 249 public boolean isInfoEnabled() { 250 return logger.isInfoEnabled(); 251 } 252 253 public void trace(final Object message) { 254 maybeLog(FQCN, org.apache.logging.log4j.Level.TRACE, message, null); 255 } 256 257 public void trace(final Object message, final Throwable t) { 258 maybeLog(FQCN, org.apache.logging.log4j.Level.TRACE, message, t); 259 } 260 261 public boolean isTraceEnabled() { 262 return logger.isTraceEnabled(); 263 } 264 265 public boolean isEnabledFor(final Priority level) { 266 final org.apache.logging.log4j.Level lvl = org.apache.logging.log4j.Level.toLevel(level.toString()); 267 return isEnabledFor(lvl); 268 } 269 270 /** 271 * No-op implementation. 272 * @param appender The Appender to add. 273 */ 274 public void addAppender(final Appender appender) { 275 } 276 277 /** 278 * No-op implementation. 279 * @param event The logging event. 280 */ 281 public void callAppenders(final LoggingEvent event) { 282 } 283 284 public Enumeration getAllAppenders() { 285 return NullEnumeration.getInstance(); 286 } 287 288 /** 289 * No-op implementation. 290 * @param name The name of the Appender. 291 * @return null. 292 */ 293 public Appender getAppender(final String name) { 294 return null; 295 } 296 297 /** 298 Is the appender passed as parameter attached to this category? 299 * @param appender The Appender to add. 300 * @return true if the appender is attached. 301 */ 302 public boolean isAttached(final Appender appender) { 303 return false; 304 } 305 306 /** 307 * No-op implementation. 308 */ 309 public void removeAllAppenders() { 310 } 311 312 /** 313 * No-op implementation. 314 * @param appender The Appender to remove. 315 */ 316 public void removeAppender(final Appender appender) { 317 } 318 319 /** 320 * No-op implementation. 321 * @param name The Appender to remove. 322 */ 323 public void removeAppender(final String name) { 324 } 325 326 /** 327 * No-op implementation. 328 */ 329 public static void shutdown() { 330 } 331 332 333 public void forcedLog(final String fqcn, final Priority level, final Object message, final Throwable t) { 334 final org.apache.logging.log4j.Level lvl = org.apache.logging.log4j.Level.toLevel(level.toString()); 335 final Message msg = message instanceof Message ? (Message) message : new ObjectMessage(message); 336 logger.log(null, fqcn, lvl, msg, t); 337 } 338 339 public boolean exists(final String name) { 340 return PrivateManager.getContext().hasLogger(name); 341 } 342 343 public boolean getAdditivity() { 344 return logger.isAdditive(); 345 } 346 347 public void setAdditivity(final boolean additivity) { 348 logger.setAdditive(additivity); 349 } 350 351 public void setResourceBundle(final ResourceBundle bundle) { 352 this.bundle = bundle; 353 } 354 355 public ResourceBundle getResourceBundle() { 356 if (bundle != null) { 357 return bundle; 358 } 359 String name = logger.getName(); 360 final ConcurrentMap<String, Logger> loggers = getLoggersMap(logger.getContext()); 361 while ((name = NameUtil.getSubName(name)) != null) { 362 if (loggers.containsKey(name)) { 363 final ResourceBundle rb = loggers.get(name).bundle; 364 if (rb != null) { 365 return rb; 366 } 367 } 368 } 369 return null; 370 } 371 372 /** 373 If <code>assertion</code> parameter is {@code false}, then 374 logs <code>msg</code> as an {@link #error(Object) error} statement. 375 376 <p>The <code>assert</code> method has been renamed to 377 <code>assertLog</code> because <code>assert</code> is a language 378 reserved word in JDK 1.4. 379 380 @param assertion The assertion. 381 @param msg The message to print if <code>assertion</code> is 382 false. 383 384 @since 1.2 385 */ 386 public void assertLog(final boolean assertion, final String msg) { 387 if (!assertion) { 388 this.error(msg); 389 } 390 } 391 392 public void l7dlog(final Priority priority, final String key, final Throwable t) { 393 if (isEnabledFor(priority)) { 394 final Message msg = new LocalizedMessage(bundle, key, null); 395 forcedLog(FQCN, priority, msg, t); 396 } 397 } 398 399 public void l7dlog(final Priority priority, final String key, final Object[] params, final Throwable t) { 400 if (isEnabledFor(priority)) { 401 final Message msg = new LocalizedMessage(bundle, key, params); 402 forcedLog(FQCN, priority, msg, t); 403 } 404 } 405 406 public void log(final Priority priority, final Object message, final Throwable t) { 407 if (isEnabledFor(priority)) { 408 final Message msg = new ObjectMessage(message); 409 forcedLog(FQCN, priority, msg, t); 410 } 411 } 412 413 public void log(final Priority priority, final Object message) { 414 if (isEnabledFor(priority)) { 415 final Message msg = new ObjectMessage(message); 416 forcedLog(FQCN, priority, msg, null); 417 } 418 } 419 420 public void log(final String fqcn, final Priority priority, final Object message, final Throwable t) { 421 if (isEnabledFor(priority)) { 422 final Message msg = new ObjectMessage(message); 423 forcedLog(fqcn, priority, msg, t); 424 } 425 } 426 427 private void maybeLog(final String fqcn, final org.apache.logging.log4j.Level level, 428 final Object message, final Throwable throwable) { 429 if (logger.isEnabled(level, null, message, throwable)) { 430 logger.log(null, FQCN, level, new ObjectMessage(message), throwable); 431 } 432 } 433 434 /** 435 * Private logger factory. 436 */ 437 private static class PrivateFactory implements LoggerFactory { 438 439 @Override 440 public Logger makeNewLoggerInstance(final LoggerContext context, final String name) { 441 return new Logger(context, name); 442 } 443 } 444 445 /** 446 * Private LogManager. 447 */ 448 private static class PrivateManager extends org.apache.logging.log4j.LogManager { 449 private static final String FQCN = Category.class.getName(); 450 451 public static org.apache.logging.log4j.spi.LoggerContext getContext() { 452 return getContext(FQCN, false); 453 } 454 455 public static org.apache.logging.log4j.Logger getLogger(final String name) { 456 return getLogger(FQCN, name); 457 } 458 } 459 460 private boolean isEnabledFor(final org.apache.logging.log4j.Level level) { 461 return logger.isEnabled(level, null, null); 462 } 463 464 }