接触log4j已经有一段时间,有必要做一个小小的总结。
关于log4j先做以下说明:
(1)可以使用 property 和 xml 两种格式的文件来配置日志记录的行为
(2)能 够定 向 输 出到 文 件、 控 制 台、 java.io.OutputStream 、java.io.Writer、远程服务器、远程 Unix Syslog 守护者、远程 JMS 监听者、NT EventLog 或者发送 e-mail
(3)使用由低到高 ALL、DEBUG、INFO、W ARN、ERROR 、 F A T AL和OFF 这 7 个级别
(4)可以容易的改变日志记录的布局(Layout),即输出格式
(5)输出日志记录的目的地和写策略可以通过实现 Appender 接口来改变
(6)支持为每个日志(logger)附加多个目的地(appender)
先从一个简单的实例说起吧。且看代码:
import java.io.IOException; import org.apache.log4j.FileAppender; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.apache.log4j.SimpleLayout; public class SimpleTest { private Logger logger; public SimpleTest(){ setLogger(); } public void setLogger() { logger = Logger.getLogger(SimpleTest.class);//传递相同的名字可以得到一个相同的logger。 SimpleLayout layout = new SimpleLayout();//创建一个简单布局 FileAppender appender = null; try { appender = new FileAppender(layout,"out.txt",false); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } logger.addAppender(appender);//信息输出到out.txt文件中 logger.setLevel(Level.INFO);//设置级别为INFO,低于这个级别的输出信息将不会被输出 } public void test(){ logger.info("before init"); try{ init(); } catch(Exception e){ logger.error("init error");//用于记录出错信息 } logger.info("after init"); } public void init(){ logger.debug("初始化SimpleTest");//这条输出将无效,因为级别是INFO,DEBUG级别低于它 throw new NullPointerException(); } public static void main(String[] args) { // TODO Auto-generated method stub new SimpleTest().test(); } }
Logger
获取logger有两种方法:Logger.getLogger(Class class)和Logger.getLogger(String name),只要传进去的参数是相同的,得到的Logger也是相同的。另外,还有个特殊的Logger:rootLogger,它是不能用名字来获取的,Logger.getRootLogger()即可获取到根记录器,它总是存在的。
Logger是分等级的,如两个Logger名为a和a.b是父子关系,继承结构由logger4j维护,因此先创建a.b后创建a也是可以的。
Appender
log4j提供了以下几种Appender:
ConsoleAppender:控制台
FileAppender:文件
DailyRollingFIleAppender:每天产生一个新的日志文件
RollingFileAppender:到达文件指定大小时产生一个新的日志文件
WriterAppender:以流的方式发送到指定地方
JDBCAppender:通过JDBC把日志信息输出到数据库中
另外要说的是,Appender 的继承层次是附加在记录器继承层次上的,但也很少用到这个继承结构,也就不多说了。
Layout
PatternLayout : Log4j 标准的布局器,可以灵活的指定布局模式
HTMLLayout:以HTML表格式布局
SimpleLayout;包含日志信息级别和信息字符串
XMLLayout:
TTCCLayout :包含日志产生的时间、线程、类别等信息
DateLayout:
如果这些不能满足要求,还可以自定义 Layout。
其中PatternLayout的配置参数有以下几个
%m 输出代码中指定的消息
%p 输出优先级,即 DEBUG,INFO,W ARN,ERROR,F A T AL
%r 输出自应用启动到输出该 log 信息耗费的毫秒数
%c 输出所属的类目,通常就是所在类的全名
%t 输出产生该日志事件的线程名
%n 输出一个回车换行符,Windows 平台为“\r\n” ,Unix 平台为“\n”
%d 输出日志时间点的日期或时间, 默认格式为 ISO8601, 也可以在其后指定格式,如: %d{yyy MMMdd HH:mm:ss,SSS},输出类似: 2002 年 10 月 18 日 22:10:28,
921
%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。例如,T estlog4.main(T estLog4.java:10)。
日志系统的使用分如下几步:获取一个Logger,配置Appender以及Layout,插入日志信息。其中配置可以使用代码,也可以使用配置文件。使用代码的话就如上面的代码所示。通过配置文件(properties和xml,这里只说xml)的话只要在过去logger后调用PropertyConfigurator.configure ( String configFilename)或者DOMConfigurator.configure ( String filename )即可。下面看看xml配置文件的编写。
xml文件格式的定义是通过org/apache/log4j/xml/log4j.dtd来完成的,各个配置元素的嵌套关系如下所示:
<!ELEMENT log4j:configuration(renderer*,appender*,(catagory|logger)*,root?,catagoryFactory?)>
以下是一个典型的xml配置文件:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d - %c -%-4r [%t] %-5p %x - %m%n" /> </layout> </appender> <logger name="log.log4j.XMLConfigTest" additivity="false"> <level value="INFO" /> <appender-ref ref="CONSOLE" /> </logger> <root> <priority value="debug" /> <appender-ref ref="CONSOLE" /> </root> </log4j:configuration>
package log.log4j; import org.apache.log4j.Logger; import org.apache.log4j.xml.DOMConfigurator; public class XMLConfigTest { public static void main(String[] args) { // TODO Auto-generated method stub Logger a = Logger.getLogger("a");//使用默认的Appender和Layout Logger b = Logger.getLogger(XMLConfigTest.class);//使用配置的Appender和Layout DOMConfigurator.configure ("log4j.xml"); a.debug("a debug"); a.info("a info"); a.fatal("a fatal"); b.debug("b debug"); b.info("b info"); b.fatal("b fatal"); } }
2014-05-01 11:09:01,113 - a -0 [main] DEBUG - a debug 2014-05-01 11:09:01,115 - a -2 [main] INFO - a info 2014-05-01 11:09:01,115 - a -2 [main] FATAL - a fatal 2014-05-01 11:09:01,115 - log.log4j.XMLConfigTest -2 [main] INFO - b info 2014-05-01 11:09:01,115 - log.log4j.XMLConfigTest -2 [main] FATAL - b fatal
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration> <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d - %c -%-4r [%t] %-5p %x - %m%n" /> </layout> </appender> <appender name="FILE" class="org.apache.log4j.FileAppender"> <param name="File" value="C:/log4j1.log"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d - %c -%-4r [%t] %-5p %x - %m%n" /> </layout> </appender> <appender name="DATABASE" class="org.apache.log4j.jdbc.JDBCAppender"> <param name="URL" value=""/> <param name="driver" value=""/> <param name="user" value="sa"/> <param name="password" value="sa"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="INSERT INTO sa.LOG4J(stamp,thread, info_level,class,message) VALUES ('%d', '%t', '%p', '%c', %m)" /> </layout> </appender> <!-- 发邮件(只有ERROR时才会发送!) --> <appender name="MAIL" class="org.apache.log4j.net.SMTPAppender"> <param name="threshold" value="debug" /> <!-- 日志的错误级别 <param name="threshold" value="fatal"/> --> <!-- 缓存文件大小,日志达到512K时发送Email --> <param name="BufferSize" value="512" /><!-- 单位K --> <param name="From" value="[email protected]" /> <param name="SMTPHost" value="smtp.163.com" /> <param name="Subject" value="juyee-log4jMessage" /> <param name="To" value="[email protected]" /> <param name="SMTPUsername" value="test" /> <param name="SMTPPassword" value="test" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss.SSS} [%p]-[%c] %m%n" /> </layout> </appender> <appender name="ASYNC" class="org.apache.log4j.AsyncAppender"> <param name="BufferSize" value="256" /> <appender-ref ref="DATABASE" /> </appender> <appender name="filelog_daily" class="org.apache.log4j.DailyRollingFileAppender"> <param name="File" value="log/daily.log" /> <param name="DatePattern" value="'daily.'yyyy-MM-dd'.log'" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="[%d{yyyy-MM-dd HH:mm:ss\} %-5p] [%t] (%c:%L) - %m%n" /> </layout> </appender> <!--通过<logger></logger>的定义可以将各个包中的类日志输出到不同的日志文件中--> <logger name="com.litt2.log4j" additivity="false"> <level value="WARN" /> <appender-ref ref="CONSOLE" /> </logger> <!--通过<category></category>的定义可以将各个包中的类日志输出到不同的日志文件中--> <category name="com.litt3"> <level value="DEBUG" /> <appender-ref ref="CONSOLE" /> <appender-ref ref="MAIL" /> </category> <root> <priority value="debug" /> <appender-ref ref="CONSOLE" /> <appender-ref ref="FILE" /> </root> </log4j:configuration>