1.HelloWorld例子
(1)添加依赖
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
(2)编写配置文件log4j.xml,放在classpath下
<?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{dd HH:mm:ss,SSS\} %-5p] [%t] %c{2\} - %m%n"/>
</layout>
</appender>
<root>
<priority value="INFO"/>
<appender-ref ref="console"/>
</root>
</log4j:configuration>
(3)在代码中使用
public class App
{
private static Logger logger = Logger.getLogger(App.class);
public static void main(String[] args) {
logger.debug("this is debug");
logger.info("this is info");
logger.warn("this is warn");
logger.error("this is error");
}
}
结果为:
[main] INFO com.mycompany.app.App - this is info
[main] WARN com.mycompany.app.App - this is warn
[main] ERROR com.mycompany.app.App - this is error
2.Log4j使用
(1)引入
一般而言,输出日志需要考虑三个问题:日志怎么输出?输出到哪里?以什么格式输出?
这三个问题的答案正好对应了Log4j中的3个类:Logger,Appender、Layout
(2)Logger
1)是日志处理的核心组件,可以有多个
2)Logger分为5个级别:DEBUG<INFO<WARN<ERROR<TATAL3)Log4j中有一条规则:假设Logger级别为P,输出设置为Q级别,如果Q>=P,则可以启动,否则屏蔽掉
4)Logger可以在配置文件中定义,也可以根据每个类生成一个,默认情况下,logger会继承rootLogger的配置
(3)Appender
1)作用
控制日志的输出位置,如控制台、文件、根据天数或者文件大小生成新的文件,以流的形式发送到其他地方等
2)实现类
org.apache.log4j.ConsoleAppender 控制台
org.apache.log4j.FileAppender 文件
org.apache.log4j.DailyRollingFileAppender 每天产生一个日志文件
org.apache.log4j.RollingFileAppender 文件大小到达指定尺寸的时候产生一个新的文件
org.apache.log4j.WriterAppender 将日志信息以流格式发送到任意指定的地方
SMTPAppender 发送邮件
SocketAppender 远程日至服务器 发送日志事件 loggingEvent 对象
3)配置时使用方式
<appender name="名称" class="Appender实现类(就是上面那些)">
<param name="参数名称1" value="参数1值" />
<param name="参数名称2" value="参数2值" />
</appender>
当然也可以自己实现Appender接口,自定义输出的地方
(4)Layout
1)作用
Appender必须使用一个与之关联的layout,才能知道以怎么的格式输出日志信息
2)实现类
org.apache.log4j.HTMLLayout 以HTML表格形式布局
org.apache.log4j.PatternLayout 可以灵活地指定布局模式
org.apache.log4j.SimpleLayout 包含日志信息的级别和信息字符串
org.apache.log4j.TTCCLayout 包含日志产生的时间、线程、类别等信息
3)使用时配置方式
<layout class="org.apache.log4j.PatternLayout">
<param name="参数名称1" value="参数1值"/>
<param name="参数名称2" value="参数2值"/>
</layout>
通常layout都直接嵌套在appender中,如下:
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%d{dd HH:mm:ss,SSS\} %-5p] [%t] %c{2\} - %m%n"/>
</layout>
</appender>
3.Log4j使用步骤
(1)定义配置文件
一般情况下使用xml或者properties文件作为配置文件
1)配置根Logger
<root>
<priority value="INFO"/>
<appender-ref ref="appender1"/>
<appender-ref ref="appender2"/>
</root>
可以配置多个appender,也就是多个打印日志的地方。
注意:
默认情况下,其他自定义的logger都会继承rootLogger的配置,例如:rootLogger输出到控制台,自定义一个logger的输出位置为文件,那么控制台和文件都会被输出日志。
如果不要继承rootLogger的配置,可以定义additivity属性为false,这样就只会输出到文件了。
代码中:logger.setAdditivity(false);
配置中:
<appender name="myFile" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="xml.log" />
<param name="Append" value="false" />
<param name="MaxBackupIndex" value="10" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%p (%c:%L)- %m%n" />
</layout>
</appender>
<logger name="bar" additivity="false">
<level value="info" />
<appender-ref ref="myConsole" />
</logger>
2)配置日志信息输出目的地Appender,与日志信息格式
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%d{dd HH:mm:ss,SSS\} %-5p] [%t] %c{2\} - %m%n"/>
</layout>
</appender>
当使用PatternLayout的时候,可以定义一下几种格式
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
%r 输出自应用启动到输出该log信息耗费的毫秒数
%c 输出所属的类目,通常就是所在类的全名
%t 输出产生该日志事件的线程名
%n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921
%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)
(2)在代码中使用Log4j
1)获得Logger
1.通过指定名字获得logger:
public static Logger getLogger( String name)
通过名字
获得配置文件中的name等于传入name的logger,
如果配置文件中不存在则会新创建一个
2.通过class获得logger
static public
Logger getLogger(Class clazz) {
return LogManager.getLogger(clazz.getName());
}
可以看出,
通过class获取实际上就是通过class的全路径名来获取。那么根据上面的理论,
就会新创建一个名称为全路径名的logger
而这种logger又会继承rootLogger,所以使用class来获得logger,最终使用的是rootLogger的配置
2)写日志
通过logger的info、debug、error等写对应级别的日志.
注意:为了提高效率,可以使用isDebugEnabled()
if(logger.isDebugEnabled())
{
log.debug("this is debug");
}
因为日志可能有多个字符串拼接的情况,先判断下可以提高效率。
slf4j的占位符可以解决这种情况
4.Log4j使用例子
(1)输出为文本文件
<appender name="file" class="org.apache.log4j.FileAppender"> <!--输出到文件(使用追加方式)-->
<param name="File" value="E:/activex.log" /> <!--设置日志文件路径-->
<layout class="org.apache.log4j.TTCCLayout"> <!--设置日志格式-->
</layout>
</appender>
(2)输出为htm文件
<appender name="file" class="org.apache.log4j.FileAppender">
<param name="File" value="E:/activex.html" />
<layout class="org.apache.log4j.HTMLLayout">
</layout>
</appender>
(3)SimpleLayout样式
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.SimpleLayout"/>
</appender>
输出结果为:
DEBUG - This is debug message.
INFO - This is info message.
ERROR - This is error message.
(4)自定义样式
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%d{dd HH:mm:ss,SSS\} %-5p] [%t] %c{2\} - %m%n"/>
</layout>
</appender>
#自定义样式
# %r 时间 0
# %t 方法名 main
# %p 优先级 DEBUG/INFO/ERROR
# %c 所属类的全名(包括包名)
# %l 发生的位置,在某个类的某行
# %m 输出代码中指定的讯息,如log(message)中的message
# %n 输出一个换行
log4j.appender.appender1.layout.ConversionPattern=%r [%t] [%p] - %c -%l -%m%n
输出结果为:
0 [main] [DEBUG] - com.coderdream.log4j.HelloLog4j - com.coderdream.log4j.HelloLog4j.main(HelloLog4j.java:16) -This is debug message.
31 [main] [INFO] - com.coderdream.log4j.HelloLog4j - com.coderdream.log4j.HelloLog4j.main(HelloLog4j.java:18) -This is info message.
31 [main] [ERROR] - com.coderdream.log4j.HelloLog4j - com.coderdream.log4j.HelloLog4j.main(HelloLog4j.java:20) -This is error message.
(4)根据包来指定日志输出级别和位置
<logger name="com.util" additivity="false">
<level value="info" />
<appender-ref ref="file"/>
</logger>
<logger name="com.pack" additivity="false">
<level value="debug" />
<appender-ref ref="console"/>
</logger>
也就是说,实际上logger的name是匹配name*即可
那么如果如果传入class,根据上面实际上是根据包名+类名来获取的,现在包已经定义了,那么使用的就是包级别的配置
比如:com.pack.App中定义了log
private static Logger logger = Logger.getLogger(App.class);
因为包名为com.pack,匹配了Logger中的com.pack,所以就会返回这个logger。而它定义了debug级别,使用名为console的appender,那么就会打印到指定位置