关于LOG

2018-12-07  本文已影响18人  不知名的蛋挞

Logger.getLogger()和LogFactory.getLog()的区别

【举例说明】

基于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提供一个统一的日志接口,简单了操作,同时避免项目与某个日志实现系统紧密耦合。它会很贴心的帮我们自动选择适当的日志实现系统(这一点非常好!),甚至不需要配置 。

这里看一下它怎么“‘很贴心的’帮我们‘自动选择’‘适当的’日志实现系统”:

  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;

可见,commons-logging总是能找到一个日志实现类,并且尽可能找到一个“最合适”的日志实现类。我说它“很贴心”实际上是因为:

为了简化配置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】

警告、错误、严重错误,这三者应该都在系统运行时检测到了一个不正常的状态,他们之间的区别,要区分还真不是那么简单的事情。我大致是这样区分的:

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 ...");
    }
}
上一篇下一篇

猜你喜欢

热点阅读