Apache Log4j配置说明html
Apache针对不一样的语言平台为作了一系列日志工具包,可应用于java、.net、php、c++,这些日志包都是免费的,使用很是方便,能够极大提升编程效率。而且,Apache为了让众多的日志工具备一个相同操做方式,还实现作了一个通用日志工具包:commons-logging,也称Jakarta Commons Logging (JCL)。commons-logging是为那些须要创建在不一样环境下使用不一样日志架构的组件或库的开发者建立的,其中包括Apache Log4j以及Java log的日志架构。把日志信息commons-logging的Log接口,并由commons-logging在运行时决定使用哪一种日志架构。如今,Apache通用日志工具commons-logging和Log4j已经成为Java日志的标准工具。编程
JCL有两个基本的抽象类:Log(基本记录器)和LogFactory(负责建立Log实例)。当commons-logging.jar被加入到CLASSPATH(一般将commons-logging.jar放在web project下的WebContent\WEB-INF\lib目录中)以后,它会合理地猜想你想用的日志工具,而后进行自我设置,用户根本不须要作任何设置。默认的LogFactory是按照下列的步骤去发现并决定那个日志工具将被使用的(按照顺序,寻找过程会在找到第一个工具时停止,这个顺序很是重要):架构
寻找当前factory中名叫org.apache.commons.logging.Log配置属性的值app
寻找系统中属性中名叫org.apache.commons.logging.Log的值工具
若是应用程序的classpath中有log4j,则使用相关的包装(wrapper)类(Log4JLogger)
若是应用程序运行在jdk1.4的系统中,使用相关的包装类(Jdk14Logger)
使用简易日志包装类(SimpleLog)
上述的加载顺序能够经过commons-logging中LogSource.java的源代码能够看出,源代码以下,具体能够参考注释:
package log.sample; public class ca { static { // Is Log4J Available?用户Log4J是否可用 try { /** * 经过Class.forName("org.apache.log4j.Logger"))来查找Log4J, * 只有将log4j.jar添加到classpath之后才能找到, * 这也是为何默认状况下只要将log4j.jar文件放在lib文件夹中 * 而不须要在common-logging.properties配置文件中进行配置就能自动使用log4j的缘由 */ if (null != Class.forName("org.apache.log4j.Logger")) { log4jIsAvailable = true; } else { log4jIsAvailable = false; } } catch (Throwable t) { log4jIsAvailable = false; } // Is JDK 1.4 Logging Available?原来同上面的Log4J try { if ((null != Class.forName("java.util.logging.Logger")) && (null != Class.forName("org.apache.commons.logging.impl.Jdk14Logger"))) { jdk14IsAvailable = true; } else { jdk14IsAvailable = false; } } catch (Throwable t) { jdk14IsAvailable = false; } // Set the default Log implementation,经过common-logging.properties配置文件来决定日志实现方式 String name = null; try { name = System.getProperty("org.apache.commons.logging.log"); if (name == null) { name = System.getProperty("org.apache.commons.logging.Log"); } } catch (Throwable t) { } if (name != null) { try { setLogImplementation(name); } catch (Throwable t) { try { setLogImplementation ("org.apache.commons.logging.impl.NoOpLog"); } catch (Throwable u) { ; } } } else { try { if (log4jIsAvailable) {//若是log4j可用,默认优先使用Log4JLogger setLogImplementation ("org.apache.commons.logging.impl.Log4JLogger"); } else if (jdk14IsAvailable) {//第二优先使用Jdk14Logger setLogImplementation ("org.apache.commons.logging.impl.Jdk14Logger"); } else {//最后使用commoms-logging中的自带的实现,但它不进行任何操做 setLogImplementation ("org.apache.commons.logging.impl.NoOpLog"); } } catch (Throwable t) { try { setLogImplementation ("org.apache.commons.logging.impl.NoOpLog"); } catch (Throwable u) { ; } } } } }
org.apache.commons.logging.Log的具体实现大体有以下几类:
-org.apache.commons.logging.impl.Jdk14Logger:使用JDK1.4。
-org.apache.commons.logging.impl.Log4JLogger:使用Log4J。
-org.apache.commons.logging.impl.Log4JCategoryLog:使用Log4J,该实现已被弃用,推荐使用Log4JLogger
-org.apache.commons.logging.impl.LogKitLogger:使用 avalon-Logkit。
-org.apache.commons.logging.impl.SimpleLog:common-logging自带日志实现类。它实现了Log接口,把日志消息都输出到系统错误流System.err 中。
-org.apache.commons.logging.impl.NoOpLog:common-logging自带日志实现类。它实现了Log接口。 其输出日志的方法中不进行任何操做。
确保日志信息在内容上和反应问题的严重程度上的恰当,是很是重要的。log4j主要有以下的信息级别:
fatal:很是严重的错误,致使系统停止。指望这类信息能当即显示在状态控制台上。
error:其它运行期错误或不是预期的条件。指望这类信息能当即显示在状态控制台上。
warn:使用了不同意使用的API、很是拙劣使用API, '几乎就是'错误, 其它运行时不合须要和不合预期的状态但还不必称为 "错误"。指望这类信息能当即显示在状态控制台上。
info:运行时产生的有意义的事件。指望这类信息能当即显示在状态控制台上。
debug:系统流程中的细节信息。指望这类信息仅被写入log文件中。
trace:更加细节的信息。指望这类信息仅被写入log文件中。
一般状况下,咱们但愿将info级别以上的日志信息输出到控制台,而debug级别以上的信息写入到log文件中,而error信息写入到一个单独的文件中去,下面咱们的实例将会实现这样的功能。
下载commons-logging.jar和log4j.jar包,而后把它们放到工程的lib目录下,引入工程中。
在属性文件common-logging.properties中设置实现接口的类。以下(这里设置Log4j为所使用的日志包):
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
这里须要注意的是,若是common-logging.properties配置使用Log4JCategoryLog,会报错误,具体见参考文献4。配置以下:
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JCategoryLog
在第三节中咱们讲到如何在项目中引入了log4j.jar,那么common-logging默认会使用log4j最为日志实现方式。
前面咱们讲到要求在控制台输入info级别的日志,而后有一个log.log记录debug级别以上的日志,一个error.log记录error级别以上的日志。log4j.properties配置以下:
### set log levels ### log4j.rootLogger = debug , stdout , D , E ### 输出到控制台 ### log4j.appender.stdout = org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target = System.out ## 输出INFO级别以上的日志 log4j.appender.stdout.Threshold = INFO log4j.appender.stdout.layout = org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern = %d{ABSOLUTE} %5p %c{1}:%L - %m%n ### 输出到日志文件 ### log4j.appender.D = org.apache.log4j.DailyRollingFileAppender log4j.appender.D.File = D:/logs/log.log log4j.appender.D.Append = true ## 输出DEBUG级别以上的日志 log4j.appender.D.Threshold = DEBUG log4j.appender.D.layout = org.apache.log4j.PatternLayout log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n ### 保存异常信息到单独文件 ### log4j.appender.E = org.apache.log4j.DailyRollingFileAppender ## 异常日志文件名 log4j.appender.E.File = D:/logs/error.log log4j.appender.E.Append = true ## 只输出ERROR级别以上的日志!!! log4j.appender.E.Threshold = ERROR log4j.appender.E.layout = org.apache.log4j.PatternLayout log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
4.4.单独使用log4j实例:Log4jTest.java
package log.sample; import org.apache.log4j.Logger; public class Log4jTest { private static Logger log = Logger.getLogger(Log4jTest.class); public void log() { log.debug("Debug info."); log.info("Info info"); log.warn("Warn info"); log.error("Error info"); log.fatal("Fatal info"); } public static void main(String[] args) { Log4jTest test = new Log4jTest(); test.log(); } }
4.5.common-logging结合log4j实例:JCLTest.java
package log.sample; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class JCLTest { private static Log log = LogFactory.getLog(JCLTest.class); public void log(){ log.debug("Debug info."); log.info("Info info"); log.warn("Warn info"); log.error("Error info"); log.fatal("Fatal info"); } public static void main(String[] args) { JCLTest test = new JCLTest(); test.log(); } }
说明:4.4和4.5的输出结果是同样的。