zoukankan      html  css  js  c++  java
  • log4j 和slf4j的比较

    log4j 和slf4j的比较
    #

    slf4j

    官网:https://www.slf4j.org/manual.html

    slf4j(simple logging facade for java)是Java的简单的日志门面,它不是具体的日志解决方案,它只服务于各种各样slf4j-logo的日志系统。这里的slf4j-logo可以是log4j,可以是jdk的日志,可以是logback,还可以是slf4j-simple等等。按照官方的说法,SLF4J是一个用于日志系统的简单Facade,允许最终用户在部署其应用时使用其所希望的日志系统。这里其实用到了一种设计模式(Facade设计模式,门面设计模式)。如下图:

    使用方式:

    在系统开发中,统一按照slf4j的API进行开发,在部署时,选择不同的日志系统包,即可自动转换到不同的日志系统上。比如:选择JDK自带的日志系统,则只需要将slf4j-api-1.5.10.jar和slf4j-jdk14-1.5.10.jar放置到classpath中即可,如果中途无法忍受JDK自带的日志系统了,想换成log4j的日志系统,仅需要用slf4j-log4j12-1.5.10.jar替换slf4j-jdk14-1.5.10.jar即可(当然也需要log4j的jar及配置文件)
    比如:

        import org.slf4j.Logger;  
        import org.slf4j.LoggerFactory;  
          
        public class Slf4jTest {  
        // 首先获得日志记录这个对象  
         private static final Logger logger = LoggerFactory.getLogger(Slf4jTest.class);  
      
        public static void main(String[] args) {  
            // 记录error信息  
            logger.error("[info message]");  
            // 记录info,还可以传入参数  
            logger.info("[info message]{},{},{},{}", "abc", false, 123, new Slf4jTest());  
            // 记录deubg信息  
            logger.debug("[debug message]");  
            // 记录trace信息  
            logger.trace("[trace message]");  
            System.out.println("hello world");  
        }  
    } 
    

    原理介绍--静态绑定

    大家看到要使用哪种日志系统,只需要将对应的日志系统所需要的jar包文件(包括slf4j提供的jar包和日志系统自身依赖的jar包,例如:slf4j-log4j12-1.5.10.jar和log4j.1.2.jar)放入classpath即可,slf4j可以自动探测具体使用哪种日志系统,这种技术被称为静态绑定。
    在实际使用中,我们通过LoggerFactory.getLogger()获得logger,查看LoggerFactory的源代码会发现如下两点,

    • LoggerFactory通过StaticLoggerBinder.getSingleton().getLoggerFactory()获得LogFactory,然后再通过该LogFactory来获取logger的

    • 但是StaticLoggerBinder类并不在slf4j-api-1.5.10.jar中,分析与具体日志系统相关的jar包,会发现每个jar包都有一个StaticLoggerBinder类的实现(如slf4j-log4j12-1.5.10.jar、slf4j-simple-1.5.10.jar、slf4j-jdk14-1.5.10.jar均有StaticLoggerBinder类实现),这就很明白了,slf4j在启动时会动态到classpath中查找StaticLoggerBinder类,找到之后就可以生成对应日志系统的日志文件了。

    这里就有一个问题了,slf4j是如何将自己的通用日志格式转成不同的日志系统的格式的呢?
    不同日志系统包都会有一个Adapter,用来在slf4j和不同日志系统之间做转换。

    我们如果使用Springboot初始化项目,那么spring-boot-starter-web中包含了slf4j的依赖,直接用就行了

    log4j

    官网:https://logging.apache.org/log4j/2.x/

    Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layouts(布局)。这里可简单理解为日志类别,日志要输出的地方和日志以何种形式输出。

    Logger

    Loggers组件被分为七个级别:

    级别 对应int值
    OFF 0,这是最高等级,为了关闭日志记录
    FATAL 100,指定非常严重的错误事件
    ERROR 200
    WARN 300
    INFO 400
    DEBUG 500
    TRACE 600
    ALL Integer.MAX_VALUE,各级包括自定义级别

    各个级别的顺序是这样那个的:

    OFF < DEBUG < INFO < WARN < ERROR < FATAL < ALL

    可以简单地理解为级别越大越重要。
    Log4j有一个规则:只输出级别不低于设定级别的日志信息,假设Loggers级别设定为INFO,则INFO、WARN、ERROR、FATAL和ALL级别的日志信息都会输出,而级别比INFO低的DEBUG则不会输出。

    Appender

    Appender用来规定日志输出的目的地是哪里,可以是控制台,文件,数据库等等。
    常见的Appender有以下几种:

    org.apache.log4j.ConsoleAppender(控制台)
    org.apache.log4j.FileAppender(文件)
    org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
    org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
    org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
    

    在配置文件中是这样配置的:

    log4j.appender.appenderName = className
    log4j.appender.appenderName.Option1 = value1
    …
    log4j.appender.appenderName.OptionN = valueN
    

    其中appenderName是Appender的名字,可以随意起,只要满足命名规范就行,Option1,Option2,…,OptionN是这个appender的各种属性。

    ConsoleAppender的选项

    Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG。
    ImmediateFlush=true:表示所有消息都会被立即输出,设为false则不输出,默认值是true。
    Target=System.err:默认值是System.out。
    

    FileAppender选项

    Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG。
    ImmediateFlush=true:表示所有消息都会被立即输出,设为false则不输出,默认值是true。
    Append=false:true表示消息增加到指定文件中,false则将消息覆盖指定的文件内容,默认值是true。
    File=D:/logs/logging.log4j:指定消息输出到logging.log4j文件中
    bufferedIO	此标志表示是否需要写入缓存启用。默认设置为false
    bufferSize	如果 bufferedI/O 启用,这表示缓冲区的大小,默认设置为8KB
    

    DailyRollingFileAppender选项

    Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG。
    ImmediateFlush=true:表示所有消息都会被立即输出,设为false则不输出,默认值是true。
    Append=false:true表示消息增加到指定文件中,false则将消息覆盖指定的文件内容,默认值是true。
    File=D:/logs/logging.log4j:指定当前消息输出到logging.log4j文件中。
    DatePattern=’.’yyyy-MM:每月滚动一次日志文件,即每月产生一个新的日志文件。当前月的日志文件名为logging.log4j,前一个月的日志文件名为logging.log4j.yyyy-MM。
    另外,也可以指定按周、天、时、分等来滚动日志文件,对应的格式如下:
    ‘.’yyyy-MM:每月
    ‘.’yyyy-ww:每周
    ‘.’yyyy-MM-dd:每天
    ‘.’yyyy-MM-dd-a:每天两次
    ‘.’yyyy-MM-dd-HH:每小时
    ‘.’yyyy-MM-dd-HH-mm:每分钟
    

    RollingFileAppender选项

    Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG。
    ImmediateFlush=true:表示所有消息都会被立即输出,设为false则不输出,默认值是true。
    Append=false:true表示消息增加到指定文件中,false则将消息覆盖指定的文件内容,默认值是true。
    File=D:/logs/logging.log4j:指定消息输出到logging.log4j文件中。
    MaxFileSize=100KB:后缀可以是KB, MB 或者GB**。在日志文件到达该大小时,将会自动滚动,即将原来的内容移到logging.log4j.1文件中。
    MaxBackupIndex=2:指定可以产生的滚动文件的最大数,例如,设为2则可以产生logging.log4j.1,logging.log4j.2两个滚动文件和一个logging.log4j文件。
    

    Layout

    Layout用来规定日志是以什么样的格式输出,需要输出哪些信息。Layout提供四种日志输出样式,如根据HTML样式、自由指定样式、包含日志级别与信息的样式和包含日志时间、线程、类别等信息的样式。
    常见的Layout如下:

    org.apache.log4j.HTMLLayout(以HTML表格形式布局)
    org.apache.log4j.PatternLayout(可以灵活地指定布局模式)
    org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)
    org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等信息)
    

    在配置文件中这样配置的:

    log4j.appender.appenderName.layout =className
    log4j.appender.appenderName.layout.Option1 = value1
    …
    log4j.appender.appenderName.layout.OptionN = valueN
    

    HTMLLayout选项

    LocationInfo=true:输出java文件名称和行号,默认值是false。
    Title=My Logging: 默认值是Log4J Log Messages。

    PatternLayout选项
    ConversionPattern=%m%n:设定以怎样的格式显示消息。
    各种格式化说明如下:

    • %p:输出日志信息的优先级,即DEBUG,INFO,WARN,ERROR,FATAL。
    • %d:输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,如:%d{yyyy/MM/dd HH:mm:ss,SSS}。
    • %r:输出自应用程序启动到输出该log信息耗费的毫秒数。
    • %t:输出产生该日志事件的线程名。
    • %l:输出日志事件的发生位置,相当于%c.%M(%F:%L)的组合,包括类全名、方法、文件名以及在代码中的行数。例如:test.TestLog4j.main(TestLog4j.java:10)。
    • %c:输出日志信息所属的类目,通常就是所在类的全名。
    • %M:输出产生日志信息的方法名。
    • %F:输出日志消息产生时所在的文件名称。
    • %L::输出代码中的行号。
    • %m::输出代码中指定的具体日志信息。
    • %n:输出一个回车换行符,Windows平台为” ”,Unix平台为” ”。
    • %x:输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。
    • %%:输出一个”%”字符。

    以下是 log4j.properties 文件的一个appender X的语法:

        # 根日志记录器(logger)的级别定义为DEBUG并连接附加器命名为X
        log4j.rootLogger = DEBUG, X
        
        # 附加器(appender)X是定义为org.apache.log4j.FileAppender并写入到一个名为“log.out”位于日志log目录下
        log4j.appender.X=org.apache.log4j.FileAppender
        log4j.appender.X.File=${log}/log.out
        
        # 定义的布局模式是%m%n,这意味着每打印日志消息之后,将加上一个换行符
        log4j.appender.X.layout=org.apache.log4j.PatternLayout
        log4j.appender.X.layout.conversionPattern=%m%n
    

    需要注意的是

    • 可以同时指定多个输出目的地,用逗号隔开。
      例如:log4j.rootLogger=INFO,A1,B2,C3
    • log4j支持UNIX风格的变量替换,如 ${variableName}.
      使用的例子:
           public class log4jExample{
               /* Get actual class name to be printed on */
              static Logger log = Logger.getLogger(log4jExample.class.getName());
              public static void main(String[] args) throws IOException,SQLException{
                  log.debug("Hello this is an debug message");
                  log.info("Hello this is an info message");
               }
           }
    
  • 相关阅读:
    Servlet的建立以及配置使用
    maven 安装 及其 创建
    错误总结
    使用分层实现业务处理
    JSP数据交互(三)
    JSP数据交互(二)
    JSP数据交互(一)
    动态网页开发基础
    记录mysql编码问题
    .net core 2.0 升级 2.1 访问mysql出现bug解决
  • 原文地址:https://www.cnblogs.com/xzwblog/p/6846240.html
Copyright © 2011-2022 走看看