1 /* 2 * Copyright 2001-2004 The Apache Software Foundation. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.apache.log4j; 18 19 import org.apache.log4j.helpers.NullEnumeration; 20 import org.slf4j.LoggerFactory; 21 import org.slf4j.Marker; 22 import org.slf4j.MarkerFactory; 23 import org.slf4j.spi.LocationAwareLogger; 24 25 import java.util.Enumeration; 26 27 /** 28 * <p> 29 * This class is a minimal implementation of the original 30 * <code>org.apache.log4j.Category</code> class (as found in log4j 1.2) by 31 * delegation of all calls to a {@link org.slf4j.Logger} instance. 32 * 33 * 34 * <p> 35 * Log4j's <code>trace</code>, <code>debug()</code>, <code>info()</code>, 36 * <code>warn()</code>, <code>error()</code> printing methods are directly 37 * mapped to their SLF4J equivalents. Log4j's <code>fatal()</code> printing 38 * method is mapped to SLF4J's <code>error()</code> method with a FATAL marker. 39 * 40 * @author Sébastien Pennec 41 * @author Ceki Gülcü 42 */ 43 @SuppressWarnings("rawtypes") 44 public class Category { 45 46 private static final String CATEGORY_FQCN = Category.class.getName(); 47 48 private final String name; 49 50 protected org.slf4j.Logger slf4jLogger; 51 private org.slf4j.spi.LocationAwareLogger locationAwareLogger; 52 53 private static final Marker FATAL_MARKER = MarkerFactory.getMarker("FATAL"); 54 Category(String name)55 Category(String name) { 56 this.name = name; 57 slf4jLogger = LoggerFactory.getLogger(name); 58 if (slf4jLogger instanceof LocationAwareLogger) { 59 locationAwareLogger = (LocationAwareLogger) slf4jLogger; 60 } 61 } 62 getInstance(Class clazz)63 public static Category getInstance(Class clazz) { 64 return Log4jLoggerFactory.getLogger(clazz.getName()); 65 } 66 getInstance(String name)67 public static Category getInstance(String name) { 68 return Log4jLoggerFactory.getLogger(name); 69 } 70 getParent()71 public final Category getParent() { 72 return null; 73 } 74 75 /** 76 * Returns the obvious. 77 * 78 * @return 79 */ getName()80 public String getName() { 81 return name; 82 } 83 getAppender(String name)84 public Appender getAppender(String name) { 85 return null; 86 } 87 getAllAppenders()88 public Enumeration getAllAppenders() { 89 return NullEnumeration.getInstance(); 90 } 91 92 /** 93 * Return the level in effect for this category/logger. 94 * 95 * <p> 96 * The result is computed by simulation. 97 * 98 * @return 99 */ getEffectiveLevel()100 public Level getEffectiveLevel() { 101 if (slf4jLogger.isTraceEnabled()) { 102 return Level.TRACE; 103 } 104 if (slf4jLogger.isDebugEnabled()) { 105 return Level.DEBUG; 106 } 107 if (slf4jLogger.isInfoEnabled()) { 108 return Level.INFO; 109 } 110 if (slf4jLogger.isWarnEnabled()) { 111 return Level.WARN; 112 } 113 return Level.ERROR; 114 } 115 116 /** 117 * Returns the assigned {@link Level}, if any, for this Category. This 118 * implementation always returns null. 119 * 120 * @return Level - the assigned Level, can be <code>null</code>. 121 */ getLevel()122 final public Level getLevel() { 123 return null; 124 } 125 126 /** 127 * @deprecated Please use {@link #getLevel} instead. 128 * @return a Level 129 */ getPriority()130 final public Level getPriority() { 131 return null; 132 } 133 134 /** 135 * Delegates to {@link org.slf4j.Logger#isDebugEnabled} method in SLF4J 136 * 137 * @return true if this logger is enabled for the level DEBUG 138 * 139 */ isDebugEnabled()140 public boolean isDebugEnabled() { 141 return slf4jLogger.isDebugEnabled(); 142 } 143 144 /** 145 * Delegates to {@link org.slf4j.Logger#isInfoEnabled} method in SLF4J 146 * 147 * @return true if this logger is enabled for the level INFO 148 */ isInfoEnabled()149 public boolean isInfoEnabled() { 150 return slf4jLogger.isInfoEnabled(); 151 } 152 153 /** 154 * Delegates to {@link org.slf4j.Logger#isWarnEnabled} method in SLF4J 155 * 156 * @return true if this logger is enabled for the level WARN 157 */ isWarnEnabled()158 public boolean isWarnEnabled() { 159 return slf4jLogger.isWarnEnabled(); 160 } 161 162 /** 163 * Delegates to {@link org.slf4j.Logger#isErrorEnabled} method in SLF4J 164 * 165 * @return true if this logger is enabled for the level ERROR 166 */ isErrorEnabled()167 public boolean isErrorEnabled() { 168 return slf4jLogger.isErrorEnabled(); 169 } 170 171 /** 172 * Determines whether the priority passed as parameter is enabled in the 173 * underlying SLF4J logger. Each log4j priority is mapped directly to its SLF4J 174 * equivalent, except for FATAL which is mapped as ERROR. 175 * 176 * @param p the priority to check against 177 * @return true if this logger is enabled for the given level, false otherwise. 178 */ isEnabledFor(Priority p)179 public boolean isEnabledFor(Priority p) { 180 switch (p.level) { 181 case Level.TRACE_INT: 182 return slf4jLogger.isTraceEnabled(); 183 case Level.DEBUG_INT: 184 return slf4jLogger.isDebugEnabled(); 185 case Level.INFO_INT: 186 return slf4jLogger.isInfoEnabled(); 187 case Level.WARN_INT: 188 return slf4jLogger.isWarnEnabled(); 189 case Level.ERROR_INT: 190 return slf4jLogger.isErrorEnabled(); 191 case Priority.FATAL_INT: 192 return slf4jLogger.isErrorEnabled(); 193 } 194 return false; 195 } 196 differentiatedLog(Marker marker, String fqcn, int level, Object message, Throwable t)197 void differentiatedLog(Marker marker, String fqcn, int level, Object message, Throwable t) { 198 199 String m = convertToString(message); 200 if (locationAwareLogger != null) { 201 locationAwareLogger.log(marker, fqcn, level, m, null, t); 202 } else { 203 switch (level) { 204 case LocationAwareLogger.TRACE_INT: 205 slf4jLogger.trace(marker, m, (Throwable) t); 206 break; 207 case LocationAwareLogger.DEBUG_INT: 208 slf4jLogger.debug(marker, m, (Throwable) t); 209 break; 210 case LocationAwareLogger.INFO_INT: 211 slf4jLogger.info(marker, m, (Throwable) t); 212 break; 213 case LocationAwareLogger.WARN_INT: 214 slf4jLogger.warn(marker, m, (Throwable) t); 215 break; 216 case LocationAwareLogger.ERROR_INT: 217 slf4jLogger.error(marker, m, (Throwable) t); 218 break; 219 } 220 } 221 } 222 223 /** 224 * Delegates to {@link org.slf4j.Logger#debug(String)} method of SLF4J. 225 * 226 * @param message a message to log 227 */ debug(Object message)228 public void debug(Object message) { 229 differentiatedLog(null, CATEGORY_FQCN, LocationAwareLogger.DEBUG_INT, message, null); 230 } 231 232 /** 233 * Delegates to {@link org.slf4j.Logger#debug(String,Throwable)} method in 234 * SLF4J. 235 * 236 * @param message a message to log 237 * @param t a throwable to log 238 */ debug(Object message, Throwable t)239 public void debug(Object message, Throwable t) { 240 differentiatedLog(null, CATEGORY_FQCN, LocationAwareLogger.DEBUG_INT, message, t); 241 } 242 243 /** 244 * Delegates to {@link org.slf4j.Logger#info(String)} method in SLF4J. 245 * 246 * @param message a message to log 247 */ info(Object message)248 public void info(Object message) { 249 differentiatedLog(null, CATEGORY_FQCN, LocationAwareLogger.INFO_INT, message, null); 250 } 251 252 /** 253 * Delegates to {@link org.slf4j.Logger#info(String,Throwable)} method in SLF4J. 254 * 255 * @param message a message to log 256 * @param t a throwable to log 257 */ info(Object message, Throwable t)258 public void info(Object message, Throwable t) { 259 differentiatedLog(null, CATEGORY_FQCN, LocationAwareLogger.INFO_INT, message, t); 260 } 261 262 /** 263 * Delegates to {@link org.slf4j.Logger#warn(String)} method in SLF4J. 264 * 265 * @param message a message to log 266 * 267 */ warn(Object message)268 public void warn(Object message) { 269 differentiatedLog(null, CATEGORY_FQCN, LocationAwareLogger.WARN_INT, message, null); 270 } 271 272 /** 273 * Delegates to {@link org.slf4j.Logger#warn(String,Throwable)} method in SLF4J. 274 * 275 * @param message a message to log 276 * @param t a throwable to log 277 * 278 */ warn(Object message, Throwable t)279 public void warn(Object message, Throwable t) { 280 differentiatedLog(null, CATEGORY_FQCN, LocationAwareLogger.WARN_INT, message, t); 281 } 282 283 /** 284 * Delegates to {@link org.slf4j.Logger#error(String)} method in SLF4J. 285 * 286 * @param message a message to log 287 * 288 */ error(Object message)289 public void error(Object message) { 290 differentiatedLog(null, CATEGORY_FQCN, LocationAwareLogger.ERROR_INT, message, null); 291 } 292 293 /** 294 * Delegates to {@link org.slf4j.Logger#error(String,Throwable)} method in 295 * SLF4J. 296 * 297 * @param message a message to log 298 * @param t a throwable to log 299 * 300 */ error(Object message, Throwable t)301 public void error(Object message, Throwable t) { 302 differentiatedLog(null, CATEGORY_FQCN, LocationAwareLogger.ERROR_INT, message, t); 303 } 304 305 /** 306 * Delegates to {@link org.slf4j.Logger#error(String)} method in SLF4J. 307 * 308 * @param message a message to log 309 * 310 */ fatal(Object message)311 public void fatal(Object message) { 312 differentiatedLog(FATAL_MARKER, CATEGORY_FQCN, LocationAwareLogger.ERROR_INT, message, null); 313 } 314 315 /** 316 * Delegates to {@link org.slf4j.Logger#error(String,Throwable)} method in 317 * SLF4J. In addition, the call is marked with a marker named "FATAL". 318 * 319 * @param message a message to log 320 * @param t a throwable to log 321 * 322 */ fatal(Object message, Throwable t)323 public void fatal(Object message, Throwable t) { 324 differentiatedLog(FATAL_MARKER, CATEGORY_FQCN, LocationAwareLogger.ERROR_INT, message, t); 325 } 326 forcedLog(String FQCN, Priority p, Object msg, Throwable t)327 protected void forcedLog(String FQCN, Priority p, Object msg, Throwable t) { 328 log(FQCN, p, msg, t); 329 } 330 331 // See also http://jira.qos.ch/browse/SLF4J-159 log(String FQCN, Priority p, Object msg, Throwable t)332 public void log(String FQCN, Priority p, Object msg, Throwable t) { 333 int levelInt = priorityToLevelInt(p); 334 differentiatedLog(null, FQCN, levelInt, msg, t); 335 } 336 log(Priority p, Object message, Throwable t)337 public void log(Priority p, Object message, Throwable t) { 338 int levelInt = priorityToLevelInt(p); 339 differentiatedLog(null, CATEGORY_FQCN, levelInt, message, t); 340 } 341 log(Priority p, Object message)342 public void log(Priority p, Object message) { 343 int levelInt = priorityToLevelInt(p); 344 differentiatedLog(null, CATEGORY_FQCN, levelInt, message, null); 345 } 346 priorityToLevelInt(Priority p)347 private int priorityToLevelInt(Priority p) { 348 switch (p.level) { 349 case Level.TRACE_INT: 350 case Level.X_TRACE_INT: 351 return LocationAwareLogger.TRACE_INT; 352 case Priority.DEBUG_INT: 353 return LocationAwareLogger.DEBUG_INT; 354 case Priority.INFO_INT: 355 return LocationAwareLogger.INFO_INT; 356 case Priority.WARN_INT: 357 return LocationAwareLogger.WARN_INT; 358 case Priority.ERROR_INT: 359 return LocationAwareLogger.ERROR_INT; 360 case Priority.FATAL_INT: 361 return LocationAwareLogger.ERROR_INT; 362 default: 363 throw new IllegalStateException("Unknown Priority " + p); 364 } 365 } 366 convertToString(Object message)367 protected final String convertToString(Object message) { 368 if (message == null) { 369 return (String) message; 370 } else { 371 return message.toString(); 372 } 373 } 374 setAdditivity(boolean additive)375 public void setAdditivity(boolean additive) { 376 // nothing to do 377 } 378 addAppender(Appender newAppender)379 public void addAppender(Appender newAppender) { 380 // nothing to do 381 } 382 setLevel(Level level)383 public void setLevel(Level level) { 384 // nothing to do 385 } 386 getAdditivity()387 public boolean getAdditivity() { 388 return false; 389 } 390 assertLog(boolean assertion, String msg)391 public void assertLog(boolean assertion, String msg) { 392 if (!assertion) 393 error(msg); 394 } 395 396 } 397