关于LOG

作者: 不知名的蛋挞 | 来源:发表于2018-12-07 20:27 被阅读18次

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

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

    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总是能找到一个日志实现类,并且尽可能找到一个“最合适”的日志实现类。我说它“很贴心”实际上是因为:

    • 可以不需要配置文件;
    • 自动判断有没有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 ...");
        }
    }
    

    相关文章

      网友评论

          本文标题:关于LOG

          本文链接:https://www.haomeiwen.com/subject/trmwqqtx.html