基于log4j-1.2.15.jar
分析log4j的实现原理
org.apache.log4j.Logger类
package org.apache.log4j;
import org.apache.log4j.spi.LoggerFactory;
import org.apache.log4j.spi.LoggerRepository;
public class Logger extends Category
{
private static final String FQCN = Logger.class.getName();
protected Logger(String name)
{
super(name);
}
public static Logger getLogger(String name)
{
return LogManager.getLogger(name);
}
//经常使用的方法
public static Logger getLogger(Class clazz)
{
return LogManager.getLogger(clazz.getName());
}
public static Logger getRootLogger()
{
return LogManager.getRootLogger();
}
public static Logger getLogger(String name, LoggerFactory factory)
{
return LogManager.getLogger(name, factory);
}
public void trace(Object message)
{
if (this.repository.isDisabled(5000)) {
return;
}
if (Level.TRACE.isGreaterOrEqual(getEffectiveLevel()))
forcedLog(FQCN, Level.TRACE, message, null);
}
public void trace(Object message, Throwable t)
{
if (this.repository.isDisabled(5000)) {
return;
}
if (Level.TRACE.isGreaterOrEqual(getEffectiveLevel()))
forcedLog(FQCN, Level.TRACE, message, t);
}
public boolean isTraceEnabled()
{
if (this.repository.isDisabled(5000)) {
return false;
}
return Level.TRACE.isGreaterOrEqual(getEffectiveLevel());
}
}
下面是Logger的父类Category类,发现log4j也是大量使用Service Provider机制来完成工具类接口的设计
package org.apache.log4j;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Vector;
import org.apache.log4j.helpers.AppenderAttachableImpl;
import org.apache.log4j.helpers.NullEnumeration;
import org.apache.log4j.spi.AppenderAttachable;
import org.apache.log4j.spi.HierarchyEventListener;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.LoggingEvent;
public class Category
implements AppenderAttachable
{
protected String name;
protected volatile Level level;
protected volatile Category parent;
private static final String FQCN = Category.class.getName();
protected ResourceBundle resourceBundle;
protected LoggerRepository repository;
AppenderAttachableImpl aai;
protected boolean additive = true;
protected Category(String name)
{
this.name = name;
}
public synchronized void addAppender(Appender newAppender)
{
if (this.aai == null) {
this.aai = new AppenderAttachableImpl();
}
this.aai.addAppender(newAppender);
this.repository.fireAddAppenderEvent(this, newAppender);
}
public void assertLog(boolean assertion, String msg)
{
if (!assertion)
error(msg);
}
public void callAppenders(LoggingEvent event)
{
int writes = 0;
for (Category c = this; c != null; c = c.parent)
{
synchronized (c) {
if (c.aai != null) {
writes += c.aai.appendLoopOnAppenders(event);
}
if (!c.additive) {
break;
}
}
}
if (writes == 0)
this.repository.emitNoAppenderWarning(this);
}
synchronized void closeNestedAppenders()
{
Enumeration enumeration = getAllAppenders();
if (enumeration != null)
while (enumeration.hasMoreElements()) {
Appender a = (Appender)enumeration.nextElement();
if ((a instanceof AppenderAttachable))
a.close();
}
}
public void debug(Object message)
{
if (this.repository.isDisabled(10000))
return;
if (Level.DEBUG.isGreaterOrEqual(getEffectiveLevel()))
forcedLog(FQCN, Level.DEBUG, message, null);
}
public void debug(Object message, Throwable t)
{
if (this.repository.isDisabled(10000))
return;
if (Level.DEBUG.isGreaterOrEqual(getEffectiveLevel()))
forcedLog(FQCN, Level.DEBUG, message, t);
}
public void error(Object message)
{
if (this.repository.isDisabled(40000))
return;
if (Level.ERROR.isGreaterOrEqual(getEffectiveLevel()))
forcedLog(FQCN, Level.ERROR, message, null);
}
public void error(Object message, Throwable t)
{
if (this.repository.isDisabled(40000))
return;
if (Level.ERROR.isGreaterOrEqual(getEffectiveLevel()))
forcedLog(FQCN, Level.ERROR, message, t);
}
/** @deprecated */
public static Logger exists(String name)
{
return LogManager.exists(name);
}
public void fatal(Object message)
{
if (this.repository.isDisabled(50000))
return;
if (Level.FATAL.isGreaterOrEqual(getEffectiveLevel()))
forcedLog(FQCN, Level.FATAL, message, null);
}
public void fatal(Object message, Throwable t)
{
if (this.repository.isDisabled(50000))
return;
if (Level.FATAL.isGreaterOrEqual(getEffectiveLevel()))
forcedLog(FQCN, Level.FATAL, message, t);
}
protected void forcedLog(String fqcn, Priority level, Object message, Throwable t)
{
callAppenders(new LoggingEvent(fqcn, this, level, message, t));
}
public boolean getAdditivity()
{
return this.additive;
}
public synchronized Enumeration getAllAppenders()
{
if (this.aai == null) {
return NullEnumeration.getInstance();
}
return this.aai.getAllAppenders();
}
public synchronized Appender getAppender(String name)
{
if ((this.aai == null) || (name == null)) {
return null;
}
return this.aai.getAppender(name);
}
public Level getEffectiveLevel()
{
for (Category c = this; c != null; c = c.parent) {
if (c.level != null)
return c.level;
}
return null;
}
/** @deprecated */
public Priority getChainedPriority()
{
for (Category c = this; c != null; c = c.parent) {
if (c.level != null)
return c.level;
}
return null;
}
/** @deprecated */
public static Enumeration getCurrentCategories()
{
return LogManager.getCurrentLoggers();
}
/** @deprecated */
public static LoggerRepository getDefaultHierarchy()
{
return LogManager.getLoggerRepository();
}
/** @deprecated */
public LoggerRepository getHierarchy()
{
return this.repository;
}
public LoggerRepository getLoggerRepository()
{
return this.repository;
}
/** @deprecated */
public static Category getInstance(String name)
{
return LogManager.getLogger(name);
}
/** @deprecated */
public static Category getInstance(Class clazz)
{
return LogManager.getLogger(clazz);
}
public final String getName()
{
return this.name;
}
public final Category getParent()
{
return this.parent;
}
public final Level getLevel()
{
return this.level;
}
/** @deprecated */
public final Level getPriority()
{
return this.level;
}
/** @deprecated */
public static final Category getRoot()
{
return LogManager.getRootLogger();
}
public ResourceBundle getResourceBundle()
{
for (Category c = this; c != null; c = c.parent) {
if (c.resourceBundle != null) {
return c.resourceBundle;
}
}
return null;
}
protected String getResourceBundleString(String key)
{
ResourceBundle rb = getResourceBundle();
if (rb == null)
{
return null;
}
try
{
return rb.getString(key);
}
catch (MissingResourceException mre) {
error("No resource is associated with key \"" + key + "\".");
}return null;
}
public void info(Object message)
{
if (this.repository.isDisabled(20000))
return;
if (Level.INFO.isGreaterOrEqual(getEffectiveLevel()))
forcedLog(FQCN, Level.INFO, message, null);
}
public void info(Object message, Throwable t)
{
if (this.repository.isDisabled(20000))
return;
if (Level.INFO.isGreaterOrEqual(getEffectiveLevel()))
forcedLog(FQCN, Level.INFO, message, t);
}
public boolean isAttached(Appender appender)
{
if ((appender == null) || (this.aai == null)) {
return false;
}
return this.aai.isAttached(appender);
}
public boolean isDebugEnabled()
{
if (this.repository.isDisabled(10000))
return false;
return Level.DEBUG.isGreaterOrEqual(getEffectiveLevel());
}
public boolean isEnabledFor(Priority level)
{
if (this.repository.isDisabled(level.level))
return false;
return level.isGreaterOrEqual(getEffectiveLevel());
}
public boolean isInfoEnabled()
{
if (this.repository.isDisabled(20000))
return false;
return Level.INFO.isGreaterOrEqual(getEffectiveLevel());
}
public void l7dlog(Priority priority, String key, Throwable t)
{
if (this.repository.isDisabled(priority.level)) {
return;
}
if (priority.isGreaterOrEqual(getEffectiveLevel())) {
String msg = getResourceBundleString(key);
if (msg == null) {
msg = key;
}
forcedLog(FQCN, priority, msg, t);
}
}
public void l7dlog(Priority priority, String key, Object[] params, Throwable t)
{
if (this.repository.isDisabled(priority.level)) {
return;
}
if (priority.isGreaterOrEqual(getEffectiveLevel())) {
String pattern = getResourceBundleString(key);
String msg;
String msg;
if (pattern == null)
msg = key;
else
msg = MessageFormat.format(pattern, params);
forcedLog(FQCN, priority, msg, t);
}
}
public void log(Priority priority, Object message, Throwable t)
{
if (this.repository.isDisabled(priority.level)) {
return;
}
if (priority.isGreaterOrEqual(getEffectiveLevel()))
forcedLog(FQCN, priority, message, t);
}
public void log(Priority priority, Object message)
{
if (this.repository.isDisabled(priority.level)) {
return;
}
if (priority.isGreaterOrEqual(getEffectiveLevel()))
forcedLog(FQCN, priority, message, null);
}
public void log(String callerFQCN, Priority level, Object message, Throwable t)
{
if (this.repository.isDisabled(level.level)) {
return;
}
if (level.isGreaterOrEqual(getEffectiveLevel()))
forcedLog(callerFQCN, level, message, t);
}
private void fireRemoveAppenderEvent(Appender appender)
{
if (appender != null)
if ((this.repository instanceof Hierarchy))
((Hierarchy)this.repository).fireRemoveAppenderEvent(this, appender);
else if ((this.repository instanceof HierarchyEventListener))
((HierarchyEventListener)this.repository).removeAppenderEvent(this, appender);
}
public synchronized void removeAllAppenders()
{
if (this.aai != null) {
Vector appenders = new Vector();
for (Enumeration iter = this.aai.getAllAppenders(); iter.hasMoreElements(); ) {
appenders.add(iter.nextElement());
}
this.aai.removeAllAppenders();
for (Enumeration iter = appenders.elements(); iter.hasMoreElements(); ) {
fireRemoveAppenderEvent((Appender)iter.nextElement());
}
this.aai = null;
}
}
public synchronized void removeAppender(Appender appender)
{
if ((appender == null) || (this.aai == null))
return;
boolean wasAttached = this.aai.isAttached(appender);
this.aai.removeAppender(appender);
if (wasAttached)
fireRemoveAppenderEvent(appender);
}
public synchronized void removeAppender(String name)
{
if ((name == null) || (this.aai == null)) return;
Appender appender = this.aai.getAppender(name);
this.aai.removeAppender(name);
if (appender != null)
fireRemoveAppenderEvent(appender);
}
public void setAdditivity(boolean additive)
{
this.additive = additive;
}
final void setHierarchy(LoggerRepository repository)
{
this.repository = repository;
}
public void setLevel(Level level)
{
this.level = level;
}
/** @deprecated */
public void setPriority(Priority priority)
{
this.level = ((Level)priority);
}
public void setResourceBundle(ResourceBundle bundle)
{
this.resourceBundle = bundle;
}
/** @deprecated */
public static void shutdown()
{
LogManager.shutdown();
}
public void warn(Object message)
{
if (this.repository.isDisabled(30000)) {
return;
}
if (Level.WARN.isGreaterOrEqual(getEffectiveLevel()))
forcedLog(FQCN, Level.WARN, message, null);
}
public void warn(Object message, Throwable t)
{
if (this.repository.isDisabled(30000))
return;
if (Level.WARN.isGreaterOrEqual(getEffectiveLevel()))
forcedLog(FQCN, Level.WARN, message, t);
}
}
看一个普通Log4j使用的例子
package com.coderdream.log4j;
import org.apache.log4j.Logger;
public class HelloLog4j {
private static Logger logger = Logger.getLogger(HelloLog4j.class);
/**
* @param args
*/
public static void main(String[] args) {
// System.out.println("This is println message.");
// 记录debug级别的信息
logger.debug("This is debug message.");
// 记录info级别的信息
logger.info("This is info message.");
// 记录error级别的信息
logger.error("This is error message.");
}
}
配置文件log4j.properties:
#可以设置级别:debug>info>error
#debug:显示debug、info、error
#info:显示info、error
#error:只error
log4j.rootLogger=debug,appender1
#log4j.rootLogger=info,appender1
#log4j.rootLogger=error,appender1
#输出到控制台
log4j.appender.appender1=org.apache.log4j.ConsoleAppender
#样式为TTCCLayout
log4j.appender.appender1.layout=org.apache.log4j.TTCCLayout
结果
[main] DEBUG com.coderdream.log4j.HelloLog4j - This is debug message.
[main] INFO com.coderdream.log4j.HelloLog4j - This is info message.
[main] ERROR com.coderdream.log4j.HelloLog4j - This is error message.