惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

小众软件
小众软件
A
About on SuperTechFans
博客园 - Franky
Engineering at Meta
Engineering at Meta
Recent Announcements
Recent Announcements
云风的 BLOG
云风的 BLOG
B
Blog
Microsoft Security Blog
Microsoft Security Blog
L
LangChain Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
U
Unit 42
Martin Fowler
Martin Fowler
Y
Y Combinator Blog
Stack Overflow Blog
Stack Overflow Blog
博客园 - 叶小钗
Vercel News
Vercel News
Apple Machine Learning Research
Apple Machine Learning Research
The Cloudflare Blog
Last Week in AI
Last Week in AI
腾讯CDC
Microsoft Azure Blog
Microsoft Azure Blog
爱范儿
爱范儿
V
V2EX
G
Google Developers Blog

博客园 - 雨中漫步的太阳

基于跨数据库的事务的一个讨论,希望参考下大家的意见 Wave帮助、技巧、术语集 从IBatis2.X 移植到IBatis3.0 sqlMapConfig and sqlMap XML 配置文件升级说明 - 雨中漫步的太阳 .NET正则基础——.NET正则类及方法应用[转载] 按钮单击ThickBox弹出窗口 推荐一款界面设计工具 Balsamiq Mockups jQuery.extend的用法 转载 qq2009 好像和金山词霸屏幕取词有冲突 错误 1 error C2664: 'TextOutW' : cannot convert parameter 4 from 'const char [5]' to 'LPCWSTR' 也发一个有道第二题的算法,练练脑子 动手改造Ibatis,使其支持文件系统存储数据列 之 看我如何给ResultMap增加属性 发一个 Window Live Writer 插件 SyntaxHighlight 代码样式 700万数据随机取10条仅用不到10ms? 动手改造Ibatis,使其支持文件系统存储数据列 之 源码下载编译和SqlMapConfig解析 IBAtisHelper 源代码放出,需要的下载吧 动手改造Ibatis,使其支持文件系统存储数据列 预览 大家讨论下,结合文件系统,给数据库瘦身方案的可行性 Ibatis SelectKey iBatis resultMap groupBy属性使用心得[转载]
使用commons-logging和log4j记录日志[转载]
雨中漫步的太阳 · 2009-05-15 · via 博客园 - 雨中漫步的太阳

***为什么要使用commons-logging+log4j
commons-logging和log4j都是[[Apache:http://www.apache.org]]下的开源项目。~
commons-logging的目的是为“所有的Java日志实现”提供一个统一的接口,使项目与日志实现工具解耦,它自身的日志功能比较弱(只有一个简单的 SimpleLog),所以一般不会单独使用它。~
Log4j的功能非常强大,是目前最主流的java日志工具。~
结合使用2者可以避免使项目与log4j紧密耦合,用户可以轻松切换到其他日志工具,同时又可以使用log4j的强大功能。~
***commons-logging如何自动选择适当的日志实现工具
我们在使用commons-logging+日志实现工具时,我们的代码只需要和commons-logging打交道,又commons- logging去选择适当的日志实现工具。这里我们看一下commons-logging是如何去选择实现工具的~
-首先在classpath下寻找自己的配置文件commons-logging.properties,如果找到,则使用其中定义的Log实现类
org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog
上面这个配置,commons-logging会使用commons-logging的SimpleLog
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
这个配置,commons-logging就会选择使用log4j
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Jdk14Logger
这个配置,commons-logging会选择jdk的logger
-如果找不到commons-logging.properties文件,则在查找是否已定义系统环境变量org.apache.commons.logging.Log,找到则使用其定义的Log实现类
-否则,查看classpath中是否有Log4j的包,如果发现,则自动使用Log4j作为日志实现类
-否则,使用JDK自身的日志实现类(JDK1.4以后才有日志实现类)
-否则,使用commons-logging自己提供的一个简单的日志实现类SimpleLog
可见,commons-logging总是能找到一个日志实现类,并且尽可能找到一个最合适的日志实现类。~
为了简化配置,我们可以不使用commons-logging的配置文件,也不设置commons-logging相关的环境变量,只需将log4j的包 放入classpath就可以了,这样就可以完成commons-logging与Log4j的结合。如果以后不想使用log4j,只需将log4j的包 从classpath中移除就可以了。
***如何在代码中输出日志
-导入所需commons-logging的类~
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-在自己的类中定义一个org.apache.commons.logging.Log类的私有静态类变量
private static Log log = LogFactory.getLog(ClassName.class);
-使用静态类变量输出日志信息~
为了方便的控制日志输出,把日志分成了不同的级别,从低到高分别是调试,信息,警告,错误,致命错误。这样我们可以通过log4j的配置决定只输出某个级 别以上的日志。例如,在开发时我们将debug(调试)及以上的日志全部输出,而在项目正常运行时,设置为只输出warn(警告)及以上的日志。
//输出调试级别的日志信息
log.debug("debug");
//输出信息级别的日志信息
log.info("information");
//输出警告级别的日志信息
log.warn("warning");
//输出错误级别的日志信息
log.error("error");
//输出致命错误级别的日志信息
log.fatal("fatal");
正因为我们可以通过配置文件来设置日志输出的级别,所以写代码时我们并不知道某条日志是不是会真正输出,比如
log.debug("debug");
在设置了日志输出级别为info(信息)或以上的情况下,是不会被真正输出的。~
这种情况下,为了节省资源,我们可以在输出一条日志前加一个判断语句,判断该日志确实会被输出的情况下才去执行输出代码,如下所示
//输出调试级别的日志信息
if(log.isDebugEnabled()){
     log.debug("debug");
}
//输出信息级别的日志信息
if(log.isInfoEnabled()){
     log.info("information");
}
//输出警告级别的日志信息
if(log.isWarnEnabled()){
     log.warn("warning");
}
//输出错误级别的日志信息
if(log.isErrorEnabled()){
     log.error("error");
}
//输出致命错误级别的日志信息
if(log.isFatalEnabled()){
     log.fatal("fatal");
}
***灵活使用log4j
在classpath下创建log4j.properties,下面讲解log4j的主要配置
-Appender~
Appender用来指明将所有的log信息存放到什么地方,Log4j中支持多种appender,如    console、files、GUI components、NT Event Loggers等,一个Logger可以拥有多个Appender,也就是你既可以将Log信息输出到屏幕,同时存储到一个文件中。~
配置Appender的语法
log4j.appender.appenderName = fully.qualified.name.of.appender.class
log4j.appender.appenderName.option1 = value1
...
log4j.appender.appenderName.optionN = valueN
Log4j提供的appender有以下几种:
org.apache.log4j.ConsoleAppender(控制台)
org.apache.log4j.FileAppender(文件)
org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生新文件)
org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
-Layout~
Layout的作用是控制Appender的输出方式,也就是格式化输出的信息。~
配置Layout的语法
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(包含日志产生的时间、线程、类别等等信息)
Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下:
%m 输出代码中指定的消息
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
%r 输出自应用启动到输出该log信息耗费的毫秒数
%c 输出所属的类目,通常就是所在类的全名
%t 输出产生该日志事件的线程名
%n 输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n”
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式
例如:%d{yyyy年MMM月dd日HH:mm:ss,SSS},输出类似:2008年4月07日15:10:58,857
%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。
例如:Testlog4.main(TestLog4.java:10)
-Logger~
Logger用来定义日志信息的输出级别和输出目的地。Logger可分为两类
log4j.rootLogger 对所有日志输出起作用
log4j.logger.xx.yy 只对xx.yy包下面的日志输出起作用
例如
log4j.rootLogger=WARN,CONSOLE 指定所有日志级别为warn,采用名为CONSOLE的Appender输出
log4j.logger.com.orsoft=DEBUG,FILE 指定com.orsoft包内的日志,级别为DEBUG,采用名为FILE的Appender来输出。
可以看到,Logger存在类似继承的关系,所有其它Logger均继承自log4j.rootLogger,log4j.logger.xx.yy继承自log4j.logger.xx。~
当某条日志符合多个Logger时,如何判断它的输出级别和输出目的地呢?
我的理解是,输出级别由最底层的Logger决定,输出目的地则是互补关系,将会输出到所有符合条件的Logger所指定的Appender。~
例如
log4j.rootLogger=WARN,CONSOLE
log4j.logger.com.orsoft=DEBUG,FILE
log4j.logger.org.aaa=ERROR
对com.orsoft下的日志,输出级别为DEBUG,输出目的地为CONSOLE和FILE~
对org.aaa下的日志,输出级别为ERROR,输出目的地为CONSOLE~
其它包下的日志,输出级别为WARN,输出目的地为CONSOLE~
log4j.rootLogger=WARN,CONSOLE
log4j.logger.com.orsoft=DEBUG,FILE,CONSOLE
log4j.logger.org.aaa=ERROR
如果这样设置,com.orsoft下的日志,输出级别为DEBUG,输出目的地为CONSOLE和FILE,但是CONSOLE会输出2遍,这是因为2个符合条件的Appender都设置了CONSOLE作为目的地。
***Appender和Layout使用的例子


# 应用于控制台

div css xhtml xml Example Source Code Example Source Code [http://www.cnblogs.com/suyuan/]

log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=DEBUG
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[thread] n%c[CATEGORY]%n%m[MESSAGE]%n%n

#应用于文件

div css xhtml xml Example Source Code Example Source Code [http://www.cnblogs.com/suyuan/]

log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=file.log
log4j.appender.FILE.Append=false
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n


# 应用于文件回滚

div css xhtml xml Example Source Code Example Source Code [http://www.cnblogs.com/suyuan/]

log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLING_FILE.Threshold=ERROR
log4j.appender.ROLLING_FILE.File=rolling.log //文件位置,也可以用变量${java.home}、rolling.log
log4j.appender.ROLLING_FILE.Append=true //true:添加 false:覆盖
log4j.appender.ROLLING_FILE.MaxFileSize=10KB //文件最大尺寸
log4j.appender.ROLLING_FILE.MaxBackupIndex=1 //备份数
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n


#应用于socket

div css xhtml xml Example Source Code Example Source Code [http://www.cnblogs.com/suyuan/]

log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender
log4j.appender.SOCKET.RemoteHost=localhost
log4j.appender.SOCKET.Port=5001
log4j.appender.SOCKET.LocationInfo=true
# Set up for Log Facter 5
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[thread]%n%c[CATEGORY]%n%m[MESSAGE]%n%n
# Log Factor 5 Appender
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000

# 发送日志给邮件

div css xhtml xml Example Source Code Example Source Code [http://www.cnblogs.com/suyuan/]

log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.MAIL.Threshold=FATAL
log4j.appender.MAIL.BufferSize=10
log4j.appender.MAIL.From=web@www.wuset.com
log4j.appender.MAIL.SMTPHost=www.wusetu.com
log4j.appender.MAIL.Subject=Log4J Message
log4j.appender.MAIL.To=web@www.wusetu.com
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

# 用于数据库

div css xhtml xml Example Source Code Example Source Code [http://www.cnblogs.com/suyuan/]

log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
log4j.appender.DATABASE.user=root
log4j.appender.DATABASE.password=
log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n')
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=SampleMessages.log4j
log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j'
log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout

#自定义Appender

div css xhtml xml Example Source Code Example Source Code [http://www.cnblogs.com/suyuan/]

log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender
log4j.appender.im.host = mail.cybercorlin.net
log4j.appender.im.username = username
log4j.appender.im.password = password
log4j.appender.im.recipient = corlin@cybercorlin.net
log4j.appender.im.layout=org.apache.log4j.PatternLayout
log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n