Logger.getLogger()和LogFactory.getLog()的区别
- Logger.getLogger()是使用log4j的方式记录日志;
- LogFactory.getLog()则来自apache的common-logging包。
【举例说明】
基于common-logging的运行方式:
package org;
import org.apache.commons.logging.Log;
import org.apache.log4j.Logger;
public class Test extends TagSupport{
public static Log log=LogFactory.getLog(Test.class);
public static void test()
{
log.debug("111");
log.info("125");
log.warn("485");
log.error("error");
}
public static void main(String[] a)
{
Test.test();
}
}
基于log4j的运行方式:
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class TestLog4j {
static Logger logger = Logger.getLogger(TestLog4j.class);
public static void main(String args[]) {
PropertyConfigurator.configure("log4j.properties");
logger.debug("Here is some DEBUG");
logger.info("Here is some INFO");
logger.warn("Here is some WARN");
logger.error("Here is some ERROR");
logger.fatal("Here is some FATAL");
}
}
【两者区别与联系】
commons-logging和Log4j一般同时使用,Commons-loggin的目的是为 “所有的Java日志实现”提供一个统一的接口,它自身的日志功能平常弱(只有一个简单的SimpleLog?),所以一般不会单独使用它。Log4j的 功能非常全面强大,是目前的首选。我发现几乎所有的Java开源项目都会用到Log4j,但我同时发现,所有用到Log4j的项目一般也同时会用到 commons-loggin。我想,大家都不希望自己的项目与Log4j绑定的太紧密吧。
简单来说,就是commons-logging最核心有用的功能是解耦,它的SimpleLog实现性能比不上其他实现,如log4j等。
Commons-logging
Commons-logging提供一个统一的日志接口,简单了操作,同时避免项目与某个日志实现系统紧密耦合。它会很贴心的帮我们自动选择适当的日志实现系统(这一点非常好!),甚至不需要配置 。
这里看一下它怎么“‘很贴心的’帮我们‘自动选择’‘适当的’日志实现系统”:
- 首先在classpath下寻找自己的配置文件commons-logging.properties,如果找到,则使用其中定义的Log实现类;
- 如果找不到commons-logging.properties文件,则在查找是否已定义系统环境变量org.apache.commons.logging.Log,找到则使用其定义的Log实现类;
- 否则,查看classpath中是否有Log4j的包,如果发现,则自动使用Log4j作为日志实现类;
- 否则,使用JDK自身的日志实现类(JDK1.4以后才有日志实现类);
- 否则,使用commons-logging自己提供的一个简单的日志实现类SimpleLog;
可见,commons-logging总是能找到一个日志实现类,并且尽可能找到一个“最合适”的日志实现类。我说它“很贴心”实际上是因为:
- 可以不需要配置文件;
- 自动判断有没有Log4j包,有则自动使用之;
- 最悲观的情况下也总能保证提供一个日志实现(SimpleLog)。
为了简化配置commons-logging,一般不使用commons-logging的配置文件,也不设置与commons-logging相关的系统 环境变量,而只需将Log4j的Jar包放置到classpash中就可以了。这样就很简单地完成了commons-logging与Log4j的融合。 如果不想用Log4j了怎么办?只需将classpath中的Log4j的Jar包删除即可。就这么简单!
Log4j
Log4j的日志级别
每个logger都有一个日志级别,用来控制日志的输出。未分配级别的logger将自动继承它最近的父logger的日志级别。Logger的由低到高级别如下:
ALL < DEBUG < INFO < WARN < ERROR < FATAL < OFF
【DEBUG】
这个级别最低的东东(当然还有比它低的——Trace,All),一般的来说,在系统实际运行过程中,一般都是不输出的。
因此这个级别的信息,可以随意的使用,任何觉得有利于在调试时更详细的了解系统运行状态的东东,比如变量的值等等,都输出来看看也无妨。
【Info】
这个应该用来反馈系统的当前状态给最终用户的,所以,在这里输出的信息,应该对最终用户具有实际意义,也就是最终用户要能够看得明白是什么意思才行。例如系统升级等。系统声明周期事件(启动、停止)、Session的生命周期事件(登录、退出等)、典型的业务逻辑异常(登录时登录失败)都从Info来输出。
从某种角度上说,Info 输出的信息可以看作是软件产品的一部分(就像那些交互界面上的文字一样),所以需要谨慎对待,不可随便。
【Warn、Error、Fatal】
警告、错误、严重错误,这三者应该都在系统运行时检测到了一个不正常的状态,他们之间的区别,要区分还真不是那么简单的事情。我大致是这样区分的:
- 所谓警告,应该是这个时候进行一些修复性的工作,应该还可以把系统恢复到正常状态中来,系统应该可以继续运行下去。
- 所谓错误,就是说可以进行一些修复性的工作,但无法确定系统会正常的工作下去,系统在以后的某个阶段,很可能会因为当前的这个问题,导致一个无法修复的错误(例如宕机),但也可能一直工作到停止也不出现严重问题。
- 所谓Fatal,那就是相当严重的了,可以肯定这种错误已经无法修复,并且如果系统继续运行下去的话,可以肯定必然会越来越乱。这时候采取的最好的措施不是试图将系统状态恢复到正常,而是尽可能地保留系统有效数据并停止运行。
Log4j优先级
如果将log level设置在某一个级别上,那么比此级别优先级高的log都能打印出来。例如,如果设置优先级为WARN,那么OFF、FATAL、ERROR、WARN 4个级别的log能正常输出,而INFO、DEBUG、TRACE、 ALL级别的log则会被忽略。
import org.apache.Log4j.*;
public class LogClass {
private static org.apache.Log4j.Logger log = Logger.getLogger(LogClass.class);
public static void main(String[] args) {
log.setLevel(Level.WARN);
log.trace("Trace Message!");
log.debug("Debug Message!");
log.info("Info Message!");
log.warn("Warn Message!");
log.error("Error Message!");
log.fatal("Fatal Message!");
}
}
编译并运行 LogClass,会产生如下输出:
Warn Message!
Error Message!
Fatal Message!
Log4j的输出终端(Appender接口)
Log4j提供了以下几个实现:
org.apache.log4j.ConsoleAppender(控制台)
org.apache.log4j.FileAppender(文件)
org.apache.log4j.DailyRollingFileAppender(每天都产生一个日志文件)
org.apache.log4j.RollingFileAppender(文件大小达到指定尺寸时产生一个新的日志文件,文件名称上会自动添加数字序号)
org.apache.log4j.WriterAppender(将日志信息以流的格式发送到任意指定的地方)
【配置示例】
### set log levels ###
log4j.rootLogger = debug , stdout , D,R
### 1.输出到控制台 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{ABSOLUTE} %5p %c{1}:%L - %m%n
### 2.输出到日志文件 ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = 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
### 3.保存异常信息到单独文件 ###
log4j.appender.R = org.apache.log4j.DailyRollingFileAppender
## 异常日志文件名
log4j.appender.R.File = logs/error.log
log4j.appender.R.Append = true
## 只输出ERROR级别以上的日志!!!
log4j.appender.R.Threshold = ERROR
log4j.appender.R.layout = org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
Commons-logging和Log4j配合使用
(1)添加依赖
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
(2)修改配置文件
修改commons-logging.properties文件:显示地指定log4j
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
并添加log4j.properties的配置文件:
log4j.rootLogger=DEBUG,console
# 输出到控制台
log4j.appender.console=org.apache.log4j.ConsoleAppender
# 设置输出样式
log4j.appender.console.layout=org.apache.log4j.PatternLayout
# 日志输出信息格式为
log4j.appender.console.layout.ConversionPattern=[%-d{yyyy-MM-dd HH:mm:ss}]-[%t-%5p]-[%C-%M(%L)]: %m%n
(3)代码中使用
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class CommonsTest {
private final static Log logger = LogFactory.getLog(CommonsTest.class);
public static void main(String[] args) {
logger.debug("DEBUG ...");
logger.info("INFO ...");
logger.error("ERROR ...");
}
}
网友评论