`
snddwfn
  • 浏览: 1031 次
  • 性别: Icon_minigender_1
  • 来自: 沈阳
社区版块
存档分类
最新评论

Log4j 使用

阅读更多
log4j配置
在强调可重用组件开发的今天,除了自己从头到尾开发一个可重用的日志操作类外,Apache为我们提供了一个强有力的日志操作包-Log4j。

Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

此外,通过Log4j其他语言接口,您可以在C、C++、.Net、PL/SQL程序中使用Log4j,其语法和用法与在Java程序中一样,使得多语言分布式系统得到一个统一一致的日志组件模块。而且,通过使用各种第三方扩展,您可以很方便地将Log4j集成到J2EE、JINI甚至是SNMP应用中。

说明:下面分为三部分,第一部分讲解如何配置log4j,第二部分为对log4j.properties配置文件中的各个属性的讲解,第三部分为对log4j的详细讲解,如果只想配置上log4j,那么只需要看前两个部分就可以,如果想对log4j深入了解,则还需看第三部分。

一、Log4j配置

第一步:加入log4j-1.2.8.jar到lib下。

第二步:在CLASSPATH下建立log4j.properties。内容如下:

1 log4j.rootCategory=INFO, stdout , R

2

3 log4j.appender.stdout=org.apache.log4j.ConsoleAppender

4 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

5 log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n

6

7 log4j.appender.R=org.apache.log4j.DailyRollingFileAppender

8 log4j.appender.R.File=D:/Tomcat 5.5/logs/qc.log

9 log4j.appender.R.layout=org.apache.log4j.PatternLayout

10 log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n

11

12 log4j.logger.com.neusoft=DEBUG

13 log4j.logger.com.opensymphony.oscache=ERROR

14 log4j.logger.net.sf.navigator=ERROR

15 log4j.logger.org.apache.commons=ERROR

16 log4j.logger.org.apache.struts=WARN

17 log4j.logger.org.displaytag=ERROR

18 log4j.logger.org.springframework=DEBUG

19 log4j.logger.com.ibatis.db=WARN

20 log4j.logger.org.apache.velocity=FATAL

21

22 log4j.logger.com.canoo.webtest=WARN

23

24 log4j.logger.org.hibernate.ps.PreparedStatementCache=WARN

25 log4j.logger.org.hibernate=DEBUG

26 log4j.logger.org.logicalcobwebs=WARN

第三步:相应的修改其中属性,修改之前就必须知道这些都是干什么的,在第二部分讲解。

第四步:在要输出日志的类中加入相关语句:

定义属性:protected final Log log = LogFactory.getLog(getClass());

在相应的方法中:

if (log.isDebugEnabled())

{

log.debug("System .....");

}

二、Log4j说明

1 log4j.rootCategory=INFO, stdout , R

此句为将等级为INFO的日志信息输出到stdout和R这两个目的地,stdout和R的定义在下面的代码,可以任意起名。等级可分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL,如果配置OFF则不打出任何信息,如果配置为INFO这样只显示INFO, WARN, ERROR的log信息,而DEBUG信息不会被显示,具体讲解可参照第三部分定义配置文件中的logger。

3 log4j.appender.stdout=org.apache.log4j.ConsoleAppender

此句为定义名为stdout的输出端是哪种类型,可以是

org.apache.log4j.ConsoleAppender(控制台),

org.apache.log4j.FileAppender(文件),

org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),

org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)

org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

具体讲解可参照第三部分定义配置文件中的Appender。

4 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

此句为定义名为stdout的输出端的layout是哪种类型,可以是

org.apache.log4j.HTMLLayout(以HTML表格形式布局),

org.apache.log4j.PatternLayout(可以灵活地指定布局模式),

org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),

org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

具体讲解可参照第三部分定义配置文件中的Layout。

5 log4j.appender.stdout.layout.ConversionPattern= [QC] %p [%t] %C.%M(%L) | %m%n

如果使用pattern布局就要指定的打印信息的具体格式ConversionPattern,打印参数如下:

%m 输出代码中指定的消息

%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL

%r 输出自应用启动到输出该log信息耗费的毫秒数

%c 输出所属的类目,通常就是所在类的全名

%t 输出产生该日志事件的线程名

%n 输出一个回车换行符,Windows平台为"rn",Unix平台为"n"

%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921

%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。

[QC]是log信息的开头,可以为任意字符,一般为项目简称。

输出的信息

[TS] DEBUG [main] AbstractBeanFactory.getBean(189) | Returning cached instance of singleton bean 'MyAutoProxy'

具体讲解可参照第三部分定义配置文件中的格式化日志信息。

7 log4j.appender.R=org.apache.log4j.DailyRollingFileAppender

此句与第3行一样。定义名为R的输出端的类型为每天产生一个日志文件。

8 log4j.appender.R.File=D:/Tomcat 5.5/logs/qc.log

此句为定义名为R的输出端的文件名为D:/Tomcat 5.5/logs/qc.log

可以自行修改。

9 log4j.appender.R.layout=org.apache.log4j.PatternLayout

与第4行相同。

10 log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n

与第5行相同。

12 log4j.logger.com. neusoft =DEBUG

指定com.neusoft包下的所有类的等级为DEBUG。

可以把com.neusoft改为自己项目所用的包名。

13 log4j.logger.com.opensymphony.oscache=ERROR

14 log4j.logger.net.sf.navigator=ERROR

这两句是把这两个包下出现的错误的等级设为ERROR,如果项目中没有配置EHCache,则不需要这两句。

15 log4j.logger.org.apache.commons=ERROR

16 log4j.logger.org.apache.struts=WARN

这两句是struts的包。

17 log4j.logger.org.displaytag=ERROR

这句是displaytag的包。(QC问题列表页面所用)

18 log4j.logger.org.springframework=DEBUG

此句为Spring的包。

24 log4j.logger.org.hibernate.ps.PreparedStatementCache=WARN

25 log4j.logger.org.hibernate=DEBUG

此两句是hibernate的包。

以上这些包的设置可根据项目的实际情况而自行定制。

三、log4j详解

1、定义配置文件

Log4j支持两种配置文件格式,一种是XML格式的文件,一种是Java特性文件log4j.properties(键=值)。下面将介绍使用log4j.properties文件作为配置文件的方法:

①、配置根Logger

Logger 负责处理日志记录的大部分操作。

其语法为:

log4j.rootLogger = [ level ] , appenderName, appenderName, ...

其中,level 是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者自定义的级别。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定义了INFO级别,只有等于及高于这个级别的才进行处理,则应用程序中所有DEBUG级别的日志信息将不被打印出来。ALL:打印所有的日志,OFF:关闭所有的日志输出。 appenderName就是指定日志信息输出到哪个地方。可同时指定多个输出目的地。

②、配置日志信息输出目的地 Appender

Appender 负责控制日志记录操作的输出。

其语法为:

log4j.appender.appenderName = fully.qualified.name.of.appender.class

log4j.appender.appenderName.option1 = value1

...

log4j.appender.appenderName.optionN = valueN

这里的appenderName为在①里定义的,可任意起名。

其中,Log4j提供的appender有以下几种:

org.apache.log4j.ConsoleAppender(控制台),

org.apache.log4j.FileAppender(文件),

org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),

org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件),可通过log4j.appender.R.MaxFileSize=100KB设置文件大小,还可通过log4j.appender.R.MaxBackupIndex=1设置为保存一个备份文件。

org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

例如:log4j.appender.stdout=org.apache.log4j.ConsoleAppender

定义一个名为stdout的输出目的地,ConsoleAppender为控制台。

③、配置日志信息的格式(布局)Layout

Layout 负责格式化Appender的输出。

其语法为:

log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class

log4j.appender.appenderName.layout.option1 = value1

...

log4j.appender.appenderName.layout.optionN = valueN

其中,Log4j提供的layout有以下几种:

org.apache.log4j.HTMLLayout(以HTML表格形式布局),

org.apache.log4j.PatternLayout(可以灵活地指定布局模式),

org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),

org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

2、格式化日志信息

Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下:

%m 输出代码中指定的消息

%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL

%r 输出自应用启动到输出该log信息耗费的毫秒数

%c 输出所属的类目,通常就是所在类的全名

%t 输出产生该日志事件的线程名

%n 输出一个回车换行符,Windows平台为"rn",Unix平台为"n"

%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921

%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。

3、在代码中使用Log4j

我们在需要输出日志信息的类中做如下的三个工作:

1、导入所有需的commongs-logging类:

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

2、在自己的类中定义一个org.apache.commons.logging.Log类的私有静态类成员:

private final Log log = LogFactory.getLog(getClass());

LogFactory.getLog()方法的参数使用的是当前类的class。

3、使用org.apache.commons.logging.Log类的成员方法输出日志信息:

if (log.isDebugEnabled())

{

log.debug("111");

}

if (log.isInfoEnabled())

{

log.info("222");

}

if (log.isWarnEnabled())

{

log.warn("333");

}

if (log.isErrorEnabled())

{

log.error("444");

}

if (log.isFatalEnabled())

{

log.fatal("555")

}
 
【LOG4J】LOG4J的使用 
送给自己的生日礼物,用了很长时间了,还没有个比较详细的了解(4月20日就写了这么多。。。本来想再补充一些,但是。。。。太懒了。。哈哈)

一 最好与commons-logging一起用,why? 

1.标准接口,即使将来脱离了log4j也一样用
2.简化了编码,减少耦合度:不需在代码中指定log4j配制文件位置,代码中不需要引用log4j的包
3.基本所有框架都是这么用的。。。。。。(我相信群众) 

附加提供一下commons-logging寻找配置文件的顺序(从别人那抄的)
1) 首先在classpath下寻找自己的配置文件commons-logging.properties,如果找到,则使用其中定义的Log实现类;
2) 如果找不到commons-logging.properties文件,则在查找是否已定义系统环境变量org.apache.commons.logging.Log,找到则使用其定义的Log实现类;
3) 否则,查看classpath中是否有Log4j的包,如果发现,则自动使用Log4j作为日志实现类;
4) 否则,使用JDK自身的日志实现类(JDK1.4以后才有日志实现类);
5) 否则,使用commons-logging自己提供的一个简单的日志实现类SimpleLog; 


二 具体实现 

1.把commons-logging的jar加到classpath中
2.把log4j的jar加到classpath中
3.在classpath的根目录下,建立log4j.properties(必须是这个地方,必须叫这个名,才不用特殊配置),可以直接复制后边的模板
4.在需要log的类中:
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory; 

 private static Log log = LogFactory.getLog(xxxx.class);
为什么要使用static?因为避免产生多个实例
为什么不使用this.class?因为是static不能用this(我经常犯这个错误。。。)
为什么不使new XXXX().getClass()?因为。。。。你猜呢?
5.根据实际需要log.debug()、log.info()、log.warn()、log.error()、log.fatal() 就可以输出不同等级的log 


三 log的等级 

1.为什么需要等级?写代码的时候可能需要很多调试信息,运行的时候可能需要显示提示信息,如果在服务器上发生严重错误的时候,可能需要给管理员发邮件。这种:调试,提示,错误就是等级。
2.都有什么等级? 调试(DEBUG)<信息(INFO)<警告(WARN)<错误(ERROR)<致命错误(FATAL)
3.怎么用? log.debug() log.info() log.warn() log.error() log.fatal()依次对应上边的等级 


四 log4j的配制 

1.基本参数解释:
⑴全局配制
log4j.rootLogger = [ level ] , appenderName, appenderName,..........appenderName
★log4j.rootLogger的意思可以理解为:根log或者所有的log
★level就是输出级别,只能设置一个值。
- 关于等级,前边已经说过了有5种,他们之间的关系可以理解为:
调试(DEBUG):包含调试(DEBUG)、信息(INFO)、警告(WARN)、错误(ERROR)、致命错误(FATAL)
信息(INFO):包含信息(INFO)、警告(WARN)、错误(ERROR)、致命错误(FATAL)
警告(WARN):包含警告(WARN)、错误(ERROR)、致命错误(FATAL)
错误(ERROR):包含错误(ERROR)、致命错误(FATAL)
致命错误(FATAL):只有他自己
这样,如果log4j.rootLogger = INFO,那么 INFO,WARN,ERROR,FATAL就全部会被输出
如果log4j.rootLogger = ERROR,那么ERROR,FATAL就全部会被输出
★appenderName就是记录的目标,目标可以多个,中间用『,』分割,appenderName是自己定义的,换句话说,名字是随便起的,起了名之后,就需要在下边设定具体配制
总结一下这部分,比如说有这么一句log4j.rootLogger = INFO , F1,F2那么就以为着要将所有INFO,WARN,ERROR,FATAL的log全部输出到F1,F2上。F1,F2是什么?往下看。。。。
⑵具体配制
log4j.appender.F1=org.apache.log4j.ConsoleAppender
log4j.appender.F1.layout=org.apache.log4j.PatternLayout 
log4j.appender.F1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n
★log4j.appender.F1=org.apache.log4j.ConsoleAppender的意思就是:将F1设置为控制台输出
- 还可以设置成什么?
org.apache.log4j.ConsoleAppender(控制台),
org.apache.log4j.FileAppender(文件),
org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),
org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件),
org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
★log4j.appender.F1.layout=org.apache.log4j.PatternLayout的意思就是:将F1的输出布局设置为自定义输出布局。
- 还可以设置成什么?
org.apache.log4j.HTMLLayout(以HTML表格形式布局)
org.apache.log4j.xml.XMLLayout(以XML形式布局)
org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
★log4j.appender.F1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n既然上边定义的是自定义输出布局,那么就要定义一下具体输出什么样了~~上边的%c %p %m 等以%开头的都是模式字符串,除了模式字符串外[]-空格等这些字符会按照原样显示。
- 模式字符串解释:
%m:消息本身
%p:消息的级别INFO,WARN,ERROR。。。
%r:从程序开始执行到当前日志产生时的时间间隔(微秒)
%c:输出当前日志动作所在的category名称。例如:如果category名称是"a.b.c","%c{2}"将会输出"b.c". {2}意谓着输出"以点分隔开的category名称的后两个组件",如果 {n}没有,将会输出整个category名称.
%t:输出当前线程的名称
%x:输出和当前线程相关联的NDC,尤其用到像java servlets这样的多客户多线程的应用中。
%n:输出平台相关的换行符。
%%:输出一个"%"字符
%d:输出日志产生时候的日期,当然可以对日期的格式进行定制。例如:%d{HH:mm:ss,SSSS}或者是%d{dd MMM yyyy HH:mm:ss,SSSS},如果没有指定后面的格式,将会输出ISO8601的格式。
%l:输出位置信息,相当于%C.%M(%F:%L)的组合。
%C:输出日志消息产生时所在的类名,如果类名是"test.page.Class1"%C{1}表示输出类名"Class1",%C{2}输出"page.Class1",而%C则输出"test.page.Class1"。
%M:输出日志消息产生时的方法名称
%F:输出日志消息产生时所在的文件名称
%L:输出代码中的行号
- 可以在%与模式字符之间加上修饰符来控制其最小宽度、最大宽度、和文本的对齐方式。如:
1)%20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,默认的情况下右对齐。
2)%-20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,"-"号指定左对齐。
3)%.30c:指定输出category的名称,最大的宽度是30,如果category的名称大于30的话,就会将左边多出的字符截掉,但小于30的话也不会有空格。
4)%20.30c:如果category的名称小于20就补空格,并且右对齐,如果其名称长于30字符,就从左边交远销出的字符截掉。
总结一下,现在来我们所配制的F1的全部内容
- 我们把它配制成了屏幕输出
- 输出的布局为:自定义布局
- 我们又定义了自定义布局的格式:日期时间(格式为:yyyy-MM-dd HH:mm:ss,SSS)[产生该日志的包名类名方法名] [等级] 信息+回车
如果想配制F2为每天产生一个日志文件,并且保存为xml,就这么写:
log4j.appender.F2=org.apache.log4j.DailyRollingFileAppender
log4j.appender.F2.layout=org.apache.log4j.xml.XMLLayout
这样就可以了吗?当然不是,既然保存为文件。。至少要指定一个文件名吧
log4j.appender.F2.File=c:/logs/log.xml
可以了吗?可以运行了。。。但是。。既然每天都产生一个文件,那么前一天的怎么办呢?
log4j.appender.F2.DatePattern=yyyyMMdd'.xml.back'
这样log4j会在第一次产生今天的log的同时,将昨天的log备份为 log文件名.扩展名yyyyMMdd.xml.back。对应我们这个文件,今天的log到明天有新log产生的时候,就会变为log.xml20070420.xml.back
这样的参数到底有多少?常用的有:
★ConsoleAppender选项
- Threshold=WARN:指定日志消息的输出最低层次。
- ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。
- Target=System.err:默认情况下是:System.out,指定输出控制台
★FileAppender 选项
- Threshold=WARN:指定日志消息的输出最低层次。
- ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。
- File=mylog.txt:指定消息输出到mylog.txt文件。
- Append=false:默认值是true,即将消息增加到指定文件中,false指将消息覆盖指定的文件内容。
★RollingFileAppender 选项
- Threshold=WARN:指定日志消息的输出最低层次。
- ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。
- File=mylog.txt:指定消息输出到mylog.txt文件。
- Append=false:默认值是true,即将消息增加到指定文件中,false指将消息覆盖指定的文件内容。
- MaxFileSize=100KB: 后缀可以是KB, MB 或者是 GB. 在日志文件到达该大小时,将会自动滚动,即将原来的内容移到mylog.log.1文件。
- MaxBackupIndex=2:指定可以产生的滚动文件的最大数。
★DailyRollingFileAppender 选项
- Threshold=WARN:指定日志消息的输出最低层次。
- ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。
- File=mylog.txt:指定消息输出到mylog.txt文件。
- Append=false:默认值是true,即将消息增加到指定文件中,false指将消息覆盖指定的文件内容。
- DatePattern='.'yyyy-ww:每周滚动一次文件,即每周产生一个新的文件。当然也可以指定按月、周、天、时和分。即对应的格式如下:
1)'.'yyyy-MM: 每月
2)'.'yyyy-ww: 每周
3)'.'yyyy-MM-dd: 每天
4)'.'yyyy-MM-dd-a: 每天两次
5)'.'yyyy-MM-dd-HH: 每小时
6)'.'yyyy-MM-dd-HH-mm: 每分钟
★PatternLayout 选项
- ConversionPattern=%m%n :指定怎样格式化指定的消息。
★HTMLLayout 选项
- LocationInfo=true:默认值是false,输出java文件名称和行号
- Title=my app file: 默认值是 Log4J Log Messages.
★XMLLayout 选项
- LocationInfo=true:默认值是false,输出java文件和行号
现在来看一下我们完整的第一个配制文件:
========================================================================================
log4j.rootLogger = INFO,F1,F2 

log4j.appender.F1=org.apache.log4j.ConsoleAppender 
log4j.appender.Threshold=DEBUG 
log4j.appender.F1.Target=System.out 
log4j.appender.F1.layout=org.apache.log4j.PatternLayout 
log4j.appender.F1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n 

log4j.appender.F2=org.apache.log4j.DailyRollingFileAppender 
log4j.appender.F2.File=c:/logs/log.xml
log4j.appender.F2.DatePattern=yyyyMMdd-HH'.xml.back' 
log4j.appender.F2.layout=org.apache.log4j.xml.XMLLayout
========================================================================================
编段代码看看效果
========================================================================================
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Main{
 private static Log log = LogFactory.getLog(Main.class);
 public static void main(String[] args) throws Exception{
log.info("info");
log.debug("debug");
log.warn("warn");
log.error("error");
} 

}
========================================================================================
运行效果
========================================================================================
2007-04-20 12:36:22,531 [cn.yyun.test.Main]-[INFO] info
2007-04-20 12:36:22,531 [cn.yyun.test.Main]-[WARN] warn
2007-04-20 12:36:22,531 [cn.yyun.test.Main]-[ERROR] error
========================================================================================
并且在c:/logs/下有log.xml生成,里边的内容为:
========================================================================================
<log4j:event logger="cn.yyun.test.Main" timestamp="1177043782531" level="INFO" thread="main">
<log4j:message><![CDATA[info]]></log4j:message>
</log4j:event> 

<log4j:event logger="cn.yyun.test.Main" timestamp="1177043782531" level="WARN" thread="main">
<log4j:message><![CDATA[warn]]></log4j:message>
</log4j:event> 

<log4j:event logger="cn.yyun.test.Main" timestamp="1177043782531" level="ERROR" thread="main">
<log4j:message><![CDATA[error]]></log4j:message>
</log4j:event>
========================================================================================
仔细看一下会发现,虽然我们在代码里写了log.debug("debug")但是debug并没有出现在log中,这是因为我们配置文件中,定义了log的等级为INFO,debug的等级小于info,所以不会显示,而warn,error的大于info,所以也会被显示出来 


2.根据package生成不同的log文件
⑴配置
log4j.logger.cn.yyun.test.abc=INFO,abc2,abc1 

log4j.appender.abc2=org.apache.log4j.ConsoleAppender 
log4j.appender.abc2.layout=org.apache.log4j.PatternLayout 
log4j.appender.abc2.layout.ConversionPattern=abc:[%p] %m%n 

log4j.appender.abc1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.abc1.File=C:/logs/abc.log
log4j.appender.abc1.DatePattern='.'yyyyMMdd
log4j.appender.abc1.layout=org.apache.log4j.PatternLayout
log4j.appender.abc1.layout.ConversionPattern=%d %r [%t] %5p - %m%n 

log4j.logger.cn.yyun.test.def=INFO,def
log4j.appender.def=org.apache.log4j.ConsoleAppender 
log4j.appender.def.layout=org.apache.log4j.PatternLayout 
log4j.appender.def.layout.ConversionPattern=def: [%p] %m%n 

把logger.cn.yyun.test.abc换成需要的package就可以了(整个log4j配制文件中只有这些就可以了 )。但是这样会有另一个问题,如果cn.yyun.test.Main这个类中,如果有log操作,会报告:log4j:WARN No appenders could be found for logger (cn.yyun.test.Main).所以要加上log4j.rootCategory=INFO,F1 这样所有的log都会被纪录了。。但是这样又做之后:cn.yyun.test.def里的log,会同时出现在def和F1中,cn.yyun.test.abc里的log,会同时出现在abc1,abc2和F1中。。。。。所以定义的时候一定要规划好。
⑵制定package的log等级
log4j.logger.org.hibernate=DEBUG


log4j.properties文件 

#### Use two appenders, one to log to console, another to log to a file
#log4j.rootLogger = info, stdout, R
log4j.rootLogger = info, R ,Console 

#Print only messages of priority WARN or higher for your category
log4j.logger.Log=INFO 

#----# First appender writes to console
#log4j.appender.stdout=org.apache.log4j.ConsoleAppender
#log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 

# Pattern to output the caller's file name and line number.
#log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n 

#----# Second appender writes to a file
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.Console=org.apache.log4j.ConsoleAppender
#==============#Internal development
log4j.appender.R.File=E:/Apache Software Foundation/Tomcat 5.0/webapps/test/mylog.log
#==============#Production 
#log4j.appender.R.File=/var/log/tomcat4/PostAPI
log4j.appender.R.DatePattern='_'yyyy-MM-dd'.log' 

# Control the maximum log file size
#log4j.appender.R.MaxFileSize=100KB
# Archive log files (one backup file here)
#log4j.appender.R.MaxBackupIndex=1 

log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n
log4j.appender.Console.layout=org.apache.log4j.SimpleLayout 

# digester and beanutils puts out an unholy amount of debug information through log4j.
# the following lines disable them
log4j.logger.org.apache.commons.digester.Digester=info
log4j.logger.org.apache.commons.beanutils.MethodUtils=info
log4j.logger.org.apache.commons.beanutils.BeanUtils=info
log4j.logger.org.apache.commons.beanutils.ConvertUtils=info 


测试类: 

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.PropertyConfigurator;
import java.io.File; 

public class MyLog4j {
 
 static Log log = LogFactory.getLog(MyLog4j.class); 

 public static void log(){
File flog = new File(""); // current directory
 String path = flog.getAbsolutePath(); // path = "E:/Apache Software Foundation/Tomcat 5.0/webapps/test";
PropertyConfigurator.configure(path + "/log4j.properties"); // 加载.properties文件 

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) {
MyLog4j test = new MyLog4j();
test.log();
}
}


XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>

<!-- org.apache.log4j.ConsoleAppender (输出到控制台),
org.apache.log4j.FileAppender (输出到文件),
org.apache.log4j.DailyRollingFileAppender
(每天输出产生一个日志文件),
org.apache.log4j.RollingFileAppender
(文件大小到达指定尺寸的时候产生一个新的文件),
可通过 log4j.appender.R.MaxFileSize=100KB 设置文件
大小,还可通过 log4j.appender.R.MaxBackupIndex=1
设置为保存一个备份文件。
org.apache.log4j.WriterAppender
(将日志信息以流格式发送到任意指定的地方) -->
 
 
<!-- 输出通道"STDOUT",输出所有信息到控制台
(也就是System.out.println()) -->
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<!--org.apache.log4j.HTMLLayout (以 HTML 表格形式布局),
org.apache.log4j.PatternLayout (可以灵活地指定Log内容布局模式),
org.apache.log4j.SimpleLayout (包含日志信息的级别和信息字符串),
org.apache.log4j.TTCCLayout 

(包含日志产生的时间、线程、类别等等信息) -->
<!-- 输出自定义内容的LOG -->
<layout class="org.apache.log4j.PatternLayout">
<!--
%m 输出代码中指定的消息
%p 输出优先级,即 DEBUG , INFO , WARN , ERROR , FATAL
%r 输出自应用启动到输出该 log 信息耗费的毫秒数
%c 输出打了Log的类名,%c{1}从类名开始输出一个,

例如com.tongshida.Action,{1}时只输出Action,

{2}输出 tongshida.Action
%C 输出.Error()方法所在的类。
%M 输出生成LOG的类当中的方法名称
%t 输出产生该日志事件的线程名
%n 输出一个回车换行符, Windows 平台为 "rn",Unix 平台为 "n"
%d 输出日志时间点的日期或时间,默认格式为 ISO8601 ,也可以在

其后指定格式,比如: %d{yyyy MMM dd HH:mm:ss,SSS} ,输出类似:

2002 年 10 月 18 日 22 : 10 : 28 , 921
%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中

的行数。
%[数值]p 输出的%p字符串长度小于[数值]时,补空格,默认右对齐,

前加-号,左对齐,这里也可以是%m等别的
%.[数值]p输出的%p字符串长度大于[数值],后面切掉。
%[数值].[数值]p 就是综合上两行。
-->
<!-- 输出时Log内容的具体定义 -->
<param name="ConversionPattern"

value="[%d{yyyy-MM-dd HH:mm:ss,SSS}][%-20c{1}]%-5p - %m%n"/>
</layout>
</appender>

<!-- 输出通道"DEBUG",输出方式是:只输出DEBUG级别的LOG,并文件

大小到达指定大小时产生新的Log文件 -->
<appender name="DEBUG" class="org.apache.log4j.RollingFileAppender">
<!-- 输出Log文件的路径和文件名 -->
<param name="File" value="logs/debug/debug.log"/>
<!-- TOMCAT等WEB服务器重新启动时,是否插入到原有的LOG文件里,

 true 插入false 新建 -->
<param name="Append" value="true"/>

<!-- 只输出定义的级别以上的LOG,因为在下面过滤LOG信息所以屏蔽 -->
<!-- param name="Threshold" value="info"/ -->
 
<!-- 因选择了RollingFileAppender了才有下面两个 MaxFileSize,

MaxBackupIndex 选项 -->
<!-- MaxFileSize是一个LOG文件的最大的文件大小,当LOG文件超过这个

值时,自动转成 *.log.1的LOG文件 -->
<param name="MaxFileSize" value="1024KB"/>
<!-- MaxBackupIndex生成自动转成 *.log.1的LOG文件的个数,设置3时最多

生成3个LOG备份文件,它们是[*.log.1][*.log.2][*.log.3] -->
<param name="MaxBackupIndex" value="2"/>
<!-- 输出时Log内容的具体定义 -->
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"

value="[%d{yyyy-MM-dd HH:mm:ss,SSS}][%-20c{1}]%-5p - %m%n"/>
</layout>
<!-- 过滤输出时Log内容,在这里,LevelMin,LevelMax都定义了DEBUG,

所以只输出DEBUG级别LOG的数据 -->
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<!-- 指定输出LOG内容的最低等级 -->
<param name="LevelMin" value="DEBUG"/>
<!-- 指定输出LOG内容的最高等级 -->
<param name="LevelMax" value="DEBUG"/>
</filter>
</appender>

<!-- 输出通道"INFO",输出方式是:只输出INFO级别的LOG,并文件大小
到达指定大小时产生新的Log文件 -->
<appender name="INFO" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="logs/info/info.log"/>
<param name="Append" value="true"/>
<param name="MaxFileSize" value="1024KB"/>
<param name="MaxBackupIndex" value="2"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"

value="[%d{yyyy-MM-dd HH:mm:ss,SSS}][%-20c{1}]%-5p - %m%n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="INFO"/>
<param name="LevelMax" value="INFO" />
</filter>
</appender>

<!-- 输出通道"WARN",输出方式是:只输出WARN级别的LOG,并文件
大小到达指定大小时产生新的Log文件 -->
<appender name="WARN" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="logs/warn/warn.log"/>
<param name="Append" value="true"/>
<param name="MaxFileSize" value="500KB"/>
<param name="MaxBackupIndex" value="2"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"

value="[%d{yyyy-MM-dd HH:mm:ss,SSS}][%-20c{50}]%-5p - %m%n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="WARN"/>
<param name="LevelMax" value="WARN"/>
</filter>
</appender>

<!-- 输出通道"ERROR",输出方式是:只输出ERROR级别的LOG,并文件
大小到达指定大小时产生新的Log文件 -->
<appender name="ERROR" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="logs/error/error.log"/>
<param name="Append" value="true"/>
<param name="MaxFileSize" value="500KB"/>
<param name="MaxBackupIndex" value="2"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="[%d{yyyy-MM-dd HH:mm:ss,SSS}][%-20c]%-5p - %m%n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="ERROR"/>
<param name="LevelMax" value="ERROR"/>
</filter>
</appender>

<!-- 输出通道"FATAL",输出方式是:只输出FATAL级别的LOG,并文件大小
到达指定大小时产生新的Log文件 -->
<appender name="FATAL" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="logs/fatal/fatal.log"/>
<param name="Append" value="true"/>
<param name="MaxFileSize" value="500KB"/>
<param name="MaxBackupIndex" value="2"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="[%d{yyyy-MM-dd HH:mm:ss,SSS}][%-20c{100}]%-5p - %m%n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="FATAL"/>
<param name="LevelMax" value="FATAL"/>
</filter>
</appender>

<!-- 输出通道"ALL",输出方式是:输出所有级别的LOG,并文件大小到达
指定大小时产生新的Log文件 -->
<appender name="ALL" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="logs/all/all.log"/>
<param name="Append" value="true"/>
<param name="MaxFileSize" value="500KB"/>
<param name="MaxBackupIndex" value="2"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"

value="[%d{yyyy-MM-dd HH:mm:ss,SSS}][%-20c{1}]%-5p - %m%n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="DEBUG"/>
<param name="LevelMax" value="FATAL"/>
</filter>
</appender>

<!-- 输出通道"EVERYDAY",输出方式是:输出指定所有级别的LOG,并每天一个
日志文件 -->
<appender name="EVERYDAY" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="logs/ereryday/ereryday.log"/>
<param name="Append" value="true"/>
<!-- param name="Threshold" value="DEBUG"/ --> 
<!-- 以日为单位输出LOG文件,每日输出一个LOG文件-->
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<!-- 以时为单位输出LOG文件,每小时输出一个LOG文件
<param name="DatePattern" value="'.'yyyy-MM-dd-HH"/>
-->
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message -->
<param name="ConversionPattern"

value="[%d{yyyy-MM-dd HH:mm:ss,SSS}][%-20c{100}]%-5p - %m%n"/>
<!-- The full pattern: Date MS Priority [Category] (Thread:NDC)
Message <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
<!-- 过滤输出时Log内容,在这里,LevelMin是DEBUG,LevelMax都FATAL,
所以输出DEBUG级别到FATAL级别的LOG数据 --> 
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="DEBUG"/>
<param name="LevelMax" value="FATAL"/>
</filter>
</appender>

<!-- 输出通道"DATABASE",输出方式是:输出所有级别的LOG到数据库 (liu注:我没用过,谁有机会试试,这个对日志管理很有用,可以开发一个日志查看系统来统一管理好多系统的日志)-->
<appender name="DATABASE" class="org.apache.log4j.jdbc.JDBCAppender">
<!--数据库的驱动,这里用的是MSSQL-->
<param name="driver" value="com.microsoft.jdbc.sqlserver.SQLServerDriver"/>
<!--这是Oracle用的驱动,在这里用MSSQL所以屏蔽掉了
<param name="driver" value="oracle.jdbc.driver.OracleDriver" />
--> <!--要连接的数据库-->
<param name="URL" 
value="jdbc:microsoft:sqlserver://192.168.0.120:
1433;DatabaseName=test" />
<!--连接数据库的用户名-->
<param name="user" value="sa" />
<!--连接数据库的密码--> 
<param name="password" value="sa" />
<!--向MSSQL数据库表LOG中插入数据的sql语句-->
<param name="sql" value=" INSERT INTO LOG
(LOGDATE,LOGLEVEL,LOGCLASS,LOGLOGGER,LOGMESSAGE)
values ('%d{yyyy-MM-dd HH:mm:ss}','%.50p', '%.50c',
'%.50l', '%.1000m')"/>
<!-- Oracle 的 insert 语句
<param name="sql" value=" insert into logrecord
(id,packageid,userid,syscodeid,info,logtime,loglevel)
values(?,?,?,?,?,to_date('%d{yyyy-MM-dd HH:mm:ss}',
'yyyy-MM-dd HH24:mi:ss'),'%p')" />
-->
<!-- 过滤输出时Log内容,在这里,LevelMin是ERROR,LevelMax都
FATAL,所以输出DEBUG级别到FATAL级别的LOG数据 --> 
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="ERROR"/>
<param name="LevelMax" value="FATAL"/>
</filter>
</appender>
 
<!-- 输出通道"HTML",输出方式是:输出所有级别的LOG到数据库 -->
<appender name="HTML" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="logs/html/htmllog.html" />
<param name="Append" value="true" />
<!-- 只输出定义的级别以上的LOG,因为在下面过滤LOG信息所以屏蔽 -->
<!-- param name="Threshold" value="info"/ -->
<param name="MaxFileSize" value="50KB"/>
<param name="MaxBackupIndex" value="2"/>
<!-- 好像现在只有固定输出格式 --> 
<!-- 输出的HTML都缺少</table></body>等代码,log4j的Bug?(liu 注:没有实践过,不知道准不准啊)
我建议是不要使用 --> 
<layout class="org.apache.log4j.HTMLLayout">
<param name="Title" value="TSD HP HTML LOG" />
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="DEBUG"/>
<param name="LevelMax" value="FATAL"/>
</filter> 
</appender>

<!-- 设置域名限制,即com.tongshida域及以下的日志均输出到下面
对应的通道中,(liu 注:原文这样写的,但是好像是将定义包中的类日志输出到不同的日志文件中,我比较倾向于这个) 
虽然下面<root>的<priority value="ERROR">设置
成ERROR,但com.tongshida下面的程序中的LOG要输出
level="DEBUG"的 DEBUG级别以上的LOG-->
<!--给客户交货时要把它屏蔽-->
<logger name="com.netease.foa">
<!-- 设置com.tongshida以下函数输出LOG的级别 -->
<level value="DEBUG"/>
<!-- 好像是指定输出通道,因为下面root里指定了所以这里屏蔽掉了
<appender-ref ref="DEBUG"/>
-->
</logger>

<root>
<!-- 设置输出范围,在这里光输出ERROR以上的,ERROR级别,
FATAL级别的LOG ,如果使用过滤器,就不要设置,直接使用下面的输出通道的ref-->
<priority value="ERROR"/>
<!-- 上边设置的输出通道,使用啥在这里定义啥,下面是都定义出来的输出通道 -->
<appender-ref ref="STDOUT"/>
<appender-ref ref="DEBUG"/>
<appender-ref ref="INFO"/>
<appender-ref ref="WARN"/>
<appender-ref ref="ERROR"/>
<appender-ref ref="FATAL"/>
<appender-ref ref="ALL"/>
<appender-ref ref="EVERYDAY"/>
<appender-ref ref="DATABASE"/>
<appender-ref ref="HTML"/>
</root>
</log4j:configuration>
转载CSDN:http://blog.csdn.net/fuxuejun/article/details/6308974
分享到:
评论

相关推荐

    log4j使用教程(详解)

    Log4j是一款广泛使用的开源日志框架,由Apache软件基金会开发。本文将深入探讨Log4j的基本概念、配置与使用方法。 1. **什么是Log4j** Log4j是一个基于Java的日志记录工具,它提供了灵活的控制来记录日志信息,...

    log4j使用详解 j2EE

    #### 四、在代码中使用Log4j 要在代码中使用Log4j,首先需要获取一个Logger实例。 - **语法**:`public static Logger getLogger(String name)` - **示例**: ```java import org.apache.log4j.Logger; ...

    Log4j使用实例

    ### Log4j 使用实例详解 #### 一、Log4j简介 Log4j 是一个开源的日志记录框架,由 Apache 软件基金会提供。它允许开发者根据需求配置日志等级,并灵活选择日志信息的输出方式。Log4j 的核心组件包括 Logger、...

    log4j使用详细方法

    **日志框架Log4j详解** Log4j是Apache组织提供的一款开源的日志记录工具,广泛应用于Java开发中。...通过阅读提供的"log4j使用方法"文档,你将能更深入地了解Log4j的配置和使用技巧,为你的开发工作带来便利。

    log4j使用详解log4j使用详解

    ### Log4j 使用详解 #### 一、Log4j简介 Log4j 是 Apache 的一个开源项目,通过使用 Log4j,开发者能够控制日志信息的输出等级及去向,从而更加灵活地处理日志信息。它具有强大的功能,简单的配置,并且能够支持...

    log4j使用笔记

    #### 四、log4j 配置详解 1. **配置文件**: - `log4j.properties` 或 `log4j.xml` 文件用于定义 log4j 的配置规则。 - 配置文件通常放置在项目的根目录或者类路径下。 - 如果未指定配置文件的位置,则 log4j 会...

    log4j.rar log4j使用方法

    标题“log4j.rar log4j使用方法”暗示了我们要讨论的是一个关于log4j日志框架的压缩包文件,其中包含了如何使用log4j的指导资料。log4j是Java编程语言中广泛使用的开源日志记录工具,它允许开发者灵活地控制日志信息...

    log4j使用配置方法及项目中的应用

    ### log4j使用配置方法及项目中的应用 #### 概述与背景 在软件开发过程中,日志记录是一项至关重要的任务,它不仅帮助开发者监控代码执行状态,还为后续的故障排查、性能优化和安全审计提供了关键信息。传统的做法...

    log4j使用简介.txt

    ### log4j 使用简介 #### 一、Log4j 概述 Log4j 是一个由 Apache 提供的开源项目,专门用于实现日志记录功能。它为开发者提供了灵活的日志记录方式,允许通过多种不同的格式来记录每一条日志信息,并且能够将这些...

    Log4j使用手册

    以下是Log4j的核心组成部分、使用方法以及日志分级的详细解释。 1. **LOG4J组成**: - **Logger**:是Log4j的核心,负责决定哪些日志信息应该被记录和哪些应该被忽略。它根据预定义的级别来过滤日志,由`org....

    Log4j使用教程

    ### 四、使用Log4j 在Java代码中,我们可以使用以下方式调用Log4j记录日志: ```java import org.apache.log4j.Logger; public class MyClass { private static final Logger logger = Logger.getLogger(MyClass...

    apache log4j使用大全

    Apache Log4j 是一个广泛使用的开源日志框架,它为Java应用程序提供了强大的日志记录功能。Log4j 的主要优点在于它的灵活性和可配置性,允许开发者根据需要调整日志的输出目的地、格式以及级别。 **配置Log4j** ...

    log4j使用实例.zip

    这个"log4j使用实例.zip"压缩包包含了关于如何在Java项目中配置和使用Log4j的示例代码,非常适合Java后端初学者学习。 首先,Log4j的核心组件包括Logger、Appender和Layout。Logger是日志信息的生产者,负责生成...

    log4j使用手册和API chm格式

    "Log4j使用手册和API"则明确指出了文档的核心内容,Log4j是一个广泛使用的Java日志库,它的API提供了丰富的日志记录功能,包括不同级别的日志输出(如DEBUG, INFO, WARN, ERROR等)、自定义日志格式、日志分发等。...

    Java Log4j使用详解

    #### 四、使用Log4j ##### 4.1 概述 Log4j是另一个非常流行的Java日志框架,由Apache基金会维护。它比JCL更加强大,支持更多的特性,比如多级日志记录、动态日志文件配置等。Log4j的核心优势在于其灵活性和强大的...

    log4j使用总结

    Log4j 建议只使用四个级别,优先级从高到低分别是 ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。 在配置文件中,我们可以定义多个日志信息输出目的地,例如...

    log4j 使用介绍

    【log4j 使用介绍】 log4j 是一个广泛使用的 Java 日志框架,它提供了一种高效、灵活的方式来记录应用程序中的事件。这篇介绍旨在帮助初学者理解 log4j 的核心概念和使用方法。 **1. 简介** 日志记录在软件开发中...

    最详细的Log4j使用教程

    Log4j是一个广泛使用的Java日志框架,由ApacheJakarta项目开发。它为开发者提供了灵活且功能丰富的日志记录机制,使应用程序中的日志管理变得简单。本教程将深入介绍如何使用Log4j进行日志记录,包括配置、基本用法...

Global site tag (gtag.js) - Google Analytics