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(LoggerContext context, 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(String name) { 069 this((LoggerContext) PrivateManager.getContext(), name); 070 } 071 072 private Category(org.apache.logging.log4j.core.Logger logger) { 073 this.logger = logger; 074 } 075 076 public static Category getInstance(String name) { 077 return getInstance((LoggerContext) PrivateManager.getContext(), name, loggerFactory); 078 } 079 080 static Category getInstance(LoggerContext context, String name) { 081 return getInstance(context, name, loggerFactory); 082 } 083 084 static Category getInstance(LoggerContext context, String name, LoggerFactory factory) { 085 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 Logger prev = loggers.putIfAbsent(name, logger); 092 return prev == null ? logger : prev; 093 } 094 095 public static Category getInstance(Class clazz) { 096 return getInstance(clazz.getName()); 097 } 098 099 static Category getInstance(LoggerContext context, 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 org.apache.logging.log4j.core.Logger parent = logger.getParent(); 113 if (parent == null) { 114 return null; 115 } 116 ConcurrentMap<String, Logger> loggers = getLoggersMap(logger.getContext()); 117 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(LoggerContext context) { 127 return getInstance(context, ""); 128 } 129 130 private static ConcurrentMap<String, Logger> getLoggersMap(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 148 @deprecated Please use {@link LogManager#getCurrentLoggers()} instead. 149 */ 150 public static Enumeration getCurrentCategories() { 151 return LogManager.getCurrentLoggers(); 152 } 153 154 public final Level getEffectiveLevel() { 155 org.apache.logging.log4j.Level level = logger.getLevel(); 156 157 switch (level) { 158 case TRACE: 159 return Level.TRACE; 160 case DEBUG: 161 return Level.DEBUG; 162 case INFO: 163 return Level.INFO; 164 case WARN: 165 return Level.WARN; 166 default: 167 return Level.ERROR; 168 } 169 } 170 171 public final Priority getChainedPriority() { 172 return getEffectiveLevel(); 173 } 174 175 public final Level getLevel() { 176 return getEffectiveLevel(); 177 } 178 179 public void setLevel(Level level) { 180 logger.setLevel(org.apache.logging.log4j.Level.toLevel(level.levelStr)); 181 } 182 183 public final Level getPriority() { 184 return getEffectiveLevel(); 185 } 186 187 public void setPriority(Priority priority) { 188 logger.setLevel(org.apache.logging.log4j.Level.toLevel(priority.levelStr)); 189 } 190 191 public void debug(Object message) { 192 maybeLog(FQCN, org.apache.logging.log4j.Level.DEBUG, message, null); 193 } 194 195 public void debug(Object message, Throwable t) { 196 maybeLog(FQCN, org.apache.logging.log4j.Level.DEBUG, message, t); 197 } 198 199 public boolean isDebugEnabled() { 200 return logger.isDebugEnabled(); 201 } 202 203 public void error(Object message) { 204 maybeLog(FQCN, org.apache.logging.log4j.Level.ERROR, message, null); 205 } 206 207 public void error(Object message, Throwable t) { 208 maybeLog(FQCN, org.apache.logging.log4j.Level.ERROR, message, t); 209 } 210 211 public boolean isErrorEnabled() { 212 return logger.isErrorEnabled(); 213 } 214 215 public void warn(Object message) { 216 maybeLog(FQCN, org.apache.logging.log4j.Level.WARN, message, null); 217 } 218 219 public void warn(Object message, Throwable t) { 220 maybeLog(FQCN, org.apache.logging.log4j.Level.WARN, message, t); 221 } 222 223 public boolean isWarnEnabled() { 224 return logger.isWarnEnabled(); 225 } 226 227 public void fatal(Object message) { 228 maybeLog(FQCN, org.apache.logging.log4j.Level.FATAL, message, null); 229 } 230 231 public void fatal(Object message, Throwable t) { 232 maybeLog(FQCN, org.apache.logging.log4j.Level.FATAL, message, t); 233 } 234 235 public boolean isFatalEnabled() { 236 return logger.isFatalEnabled(); 237 } 238 239 public void info(Object message) { 240 maybeLog(FQCN, org.apache.logging.log4j.Level.INFO, message, null); 241 } 242 243 public void info(Object message, Throwable t) { 244 maybeLog(FQCN, org.apache.logging.log4j.Level.INFO, message, t); 245 } 246 247 public boolean isInfoEnabled() { 248 return logger.isInfoEnabled(); 249 } 250 251 public void trace(Object message) { 252 maybeLog(FQCN, org.apache.logging.log4j.Level.TRACE, message, null); 253 } 254 255 public void trace(Object message, Throwable t) { 256 maybeLog(FQCN, org.apache.logging.log4j.Level.TRACE, message, t); 257 } 258 259 public boolean isTraceEnabled() { 260 return logger.isTraceEnabled(); 261 } 262 263 public boolean isEnabledFor(Priority level) { 264 org.apache.logging.log4j.Level lvl = org.apache.logging.log4j.Level.toLevel(level.toString()); 265 return isEnabledFor(lvl); 266 } 267 268 /** 269 * No-op implementation. 270 * @param appender The Appender to add. 271 */ 272 public void addAppender(Appender appender) { 273 } 274 275 /** 276 * No-op implementation. 277 * @param event The logging event. 278 */ 279 public void callAppenders(LoggingEvent event) { 280 } 281 282 public Enumeration getAllAppenders() { 283 return NullEnumeration.getInstance(); 284 } 285 286 /** 287 * No-op implementation. 288 * @param name The name of the Appender. 289 * @return null. 290 */ 291 public Appender getAppender(String name) { 292 return null; 293 } 294 295 /** 296 Is the appender passed as parameter attached to this category? 297 @param appender The Appender to add. 298 */ 299 public boolean isAttached(Appender appender) { 300 return false; 301 } 302 303 /** 304 * No-op implementation. 305 */ 306 public void removeAllAppenders() { 307 } 308 309 /** 310 * No-op implementation. 311 * @param appender The Appender to remove. 312 */ 313 public void removeAppender(Appender appender) { 314 } 315 316 /** 317 * No-op implementation. 318 * @param name The Appender to remove. 319 */ 320 public void removeAppender(String name) { 321 } 322 323 /** 324 * No-op implementation. 325 */ 326 public static void shutdown() { 327 } 328 329 330 public void forcedLog(String fqcn, Priority level, Object message, Throwable t) { 331 org.apache.logging.log4j.Level lvl = org.apache.logging.log4j.Level.toLevel(level.toString()); 332 Message msg = message instanceof Message ? (Message) message : new ObjectMessage(message); 333 logger.log(null, fqcn, lvl, msg, t); 334 } 335 336 public boolean exists(String name) { 337 return PrivateManager.getContext().hasLogger(name); 338 } 339 340 public boolean getAdditivity() { 341 return logger.isAdditive(); 342 } 343 344 public void setAdditivity(boolean additivity) { 345 logger.setAdditive(additivity); 346 } 347 348 public void setResourceBundle(ResourceBundle bundle) { 349 this.bundle = bundle; 350 } 351 352 public ResourceBundle getResourceBundle() { 353 if (bundle != null) { 354 return bundle; 355 } 356 int i = 0; 357 String name = logger.getName(); 358 ConcurrentMap<String, Logger> loggers = getLoggersMap(logger.getContext()); 359 while ((name = NameUtil.getSubName(name)) != null) { 360 if (loggers.containsKey(name)) { 361 ResourceBundle rb = loggers.get(name).bundle; 362 if (rb != null) { 363 return rb; 364 } 365 } 366 } 367 return null; 368 } 369 370 /** 371 If <code>assertion</code> parameter is {@code false}, then 372 logs <code>msg</code> as an {@link #error(Object) error} statement. 373 374 <p>The <code>assert</code> method has been renamed to 375 <code>assertLog</code> because <code>assert</code> is a language 376 reserved word in JDK 1.4. 377 378 @param assertion The assertion. 379 @param msg The message to print if <code>assertion</code> is 380 false. 381 382 @since 1.2 383 */ 384 public void assertLog(boolean assertion, String msg) { 385 if (!assertion) { 386 this.error(msg); 387 } 388 } 389 390 public void l7dlog(Priority priority, String key, Throwable t) { 391 if (isEnabledFor(priority)) { 392 Message msg = new LocalizedMessage(bundle, key, null); 393 forcedLog(FQCN, priority, msg, t); 394 } 395 } 396 397 public void l7dlog(Priority priority, String key, Object[] params, Throwable t) { 398 if (isEnabledFor(priority)) { 399 Message msg = new LocalizedMessage(bundle, key, params); 400 forcedLog(FQCN, priority, msg, t); 401 } 402 } 403 404 public void log(Priority priority, Object message, Throwable t) { 405 if (isEnabledFor(priority)) { 406 Message msg = new ObjectMessage(message); 407 forcedLog(FQCN, priority, msg, t); 408 } 409 } 410 411 public void log(Priority priority, Object message) { 412 if (isEnabledFor(priority)) { 413 Message msg = new ObjectMessage(message); 414 forcedLog(FQCN, priority, msg, null); 415 } 416 } 417 418 public void log(String fqcn, Priority priority, Object message, Throwable t) { 419 if (isEnabledFor(priority)) { 420 Message msg = new ObjectMessage(message); 421 forcedLog(fqcn, priority, msg, t); 422 } 423 } 424 425 private void maybeLog(String fqcn, org.apache.logging.log4j.Level level, 426 Object message, Throwable throwable) { 427 if (logger.isEnabled(level, null, message, throwable)) { 428 logger.log(null, FQCN, level, new ObjectMessage(message), throwable); 429 } 430 } 431 432 /** 433 * Private logger factory. 434 */ 435 private static class PrivateFactory implements LoggerFactory { 436 437 public Logger makeNewLoggerInstance(LoggerContext context, String name) { 438 return new Logger(context, name); 439 } 440 } 441 442 /** 443 * Private LogManager. 444 */ 445 private static class PrivateManager extends org.apache.logging.log4j.LogManager { 446 private static final String FQCN = Category.class.getName(); 447 448 public static org.apache.logging.log4j.spi.LoggerContext getContext() { 449 return getContext(FQCN, false); 450 } 451 452 public static org.apache.logging.log4j.Logger getLogger(String name) { 453 return getLogger(FQCN, name); 454 } 455 } 456 457 private boolean isEnabledFor(org.apache.logging.log4j.Level level) { 458 return logger.isEnabled(level, null, null); 459 } 460 461 }