001/* 002 * Copyright 2001-2004 The Apache Software Foundation. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.apache.log4j; 018 019import org.apache.log4j.helpers.NullEnumeration; 020import org.slf4j.LoggerFactory; 021import org.slf4j.Marker; 022import org.slf4j.MarkerFactory; 023import org.slf4j.spi.LocationAwareLogger; 024 025import java.util.Enumeration; 026 027/** 028 * <p> 029 * This class is a minimal implementation of the original 030 * <code>org.apache.log4j.Category</code> class (as found in log4j 1.2) by 031 * delegation of all calls to a {@link org.slf4j.Logger} instance. 032 * 033 * 034 * <p> 035 * Log4j's <code>trace</code>, <code>debug()</code>, <code>info()</code>, 036 * <code>warn()</code>, <code>error()</code> printing methods are directly 037 * mapped to their SLF4J equivalents. Log4j's <code>fatal()</code> printing 038 * method is mapped to SLF4J's <code>error()</code> method with a FATAL marker. 039 * 040 * @author Sébastien Pennec 041 * @author Ceki Gülcü 042 */ 043@SuppressWarnings("rawtypes") 044public class Category { 045 046 private static final String CATEGORY_FQCN = Category.class.getName(); 047 048 private final String name; 049 050 protected org.slf4j.Logger slf4jLogger; 051 private org.slf4j.spi.LocationAwareLogger locationAwareLogger; 052 053 private static final Marker FATAL_MARKER = MarkerFactory.getMarker("FATAL"); 054 055 Category(String name) { 056 this.name = name; 057 slf4jLogger = LoggerFactory.getLogger(name); 058 if (slf4jLogger instanceof LocationAwareLogger) { 059 locationAwareLogger = (LocationAwareLogger) slf4jLogger; 060 } 061 } 062 063 public static Category getInstance(Class clazz) { 064 return Log4jLoggerFactory.getLogger(clazz.getName()); 065 } 066 067 public static Category getInstance(String name) { 068 return Log4jLoggerFactory.getLogger(name); 069 } 070 071 public final Category getParent() { 072 return null; 073 } 074 075 /** 076 * Returns the obvious. 077 * 078 * @return 079 */ 080 public String getName() { 081 return name; 082 } 083 084 public Appender getAppender(String name) { 085 return null; 086 } 087 088 public Enumeration getAllAppenders() { 089 return NullEnumeration.getInstance(); 090 } 091 092 /** 093 * Return the level in effect for this category/logger. 094 * 095 * <p> 096 * The result is computed by simulation. 097 * 098 * @return 099 */ 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 */ 122 final public Level getLevel() { 123 return null; 124 } 125 126 /** 127 * @deprecated Please use {@link #getLevel} instead. 128 * @return a Level 129 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 323 public void fatal(Object message, Throwable t) { 324 differentiatedLog(FATAL_MARKER, CATEGORY_FQCN, LocationAwareLogger.ERROR_INT, message, t); 325 } 326 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 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 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 342 public void log(Priority p, Object message) { 343 int levelInt = priorityToLevelInt(p); 344 differentiatedLog(null, CATEGORY_FQCN, levelInt, message, null); 345 } 346 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 367 protected final String convertToString(Object message) { 368 if (message == null) { 369 return (String) message; 370 } else { 371 return message.toString(); 372 } 373 } 374 375 public void setAdditivity(boolean additive) { 376 // nothing to do 377 } 378 379 public void addAppender(Appender newAppender) { 380 // nothing to do 381 } 382 383 public void setLevel(Level level) { 384 // nothing to do 385 } 386 387 public boolean getAdditivity() { 388 return false; 389 } 390 391 public void assertLog(boolean assertion, String msg) { 392 if (!assertion) 393 error(msg); 394 } 395 396}