• log4j/Logback/SLF4j


    1.概念

    JUL、JCL、Jboss-logging、logback、log4j、log4j2、slf4j....等等很多,一般我们使用SLF4j作为日志的抽象层,Logback或者Log4j2作为实现类,log4j自身由于效率问题被淘汰,Logback与log4j与SLF4j是同一个人写的,springboot默认使用SLF4j+Logback

    2.SLF4j

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

    依赖

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.25</version>
    </dependency>
    

    基本使用

     @Test
        public  void testLog4J(){
            Logger logger=LoggerFactory.getLogger(MvcDemoApplicationTests.class);
            logger.warn("警告");//保存日志级别warn,还有info,error,fatal,debug,与level级别一致
        }
    

    3. SLF4j统一日志的原理

    即使是别的框架也统一使用slf4j进行输出

    原理:先要排除别的日志的依赖,然后使用相应的SLF4j的jar替换掉原来的jar,然后倒入相应的实现或者适配包以及实现,原理图如下

    相应的SLF4j的jar有下图可知是采用偷梁换柱的方式修改了相应的日志类

    排除日志包的依赖

    <dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-core</artifactId>
    			<exclusions>
    				<exclusion>
    					<groupId>commons-logging</groupId>
    					<artifactId>commons-logging</artifactId>
    				</exclusion>
    			</exclusions>
    </dependency>
    

    4. spring与springboot的日志记录

    SpringBoot能自动适配所有的日志(原因是假如了相应的适配包),底层使用slf4j+logback的方式记录日志,引入其他框架的时候,只需要把这个框架依赖的日志框架排除掉即可;

    logback-spring.xml:添加-spring后,日志框架就不直接加载日志的配置项,而是由SpringBoot解析加载,可以使用SpringBoot的高级Profile功能,假如没有-spring,那么由logback会直接加载

    spring使用自动适配所有的日志时需要的依赖

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring‐boot‐starter‐logging</artifactId>
    </dependency>
    

     添加上述依赖后的依赖关系图

    springboot的Logback文件的配置(spring-boot-1.5.17.RELEASE.jar下)

    假如需要对日志配置文件进行修改见Logback

    5. Logback

    Logback与Log4J对比

    相对Logback 执行更快,更充分的测试,原生实现了 SLF4J API(有上述可知Log4J 还需要有一个中间转换层),内容更丰富的文档,支持 XML 或者 Groovy 方式配置,配置文件自动热加载,从 IO 错误中优雅恢复,自动删除日志归档,自动压缩日志成为归档文件,支持 Prudent 模式,使多个 JVM 进程能记录同一个日志文件,支持配置文件中加入条件判断来适应不同的环境,更强大的过滤器,支持 SiftingAppender(可筛选 Appender),异常栈信息带有包信息。

    Logback的日志级别

    TRACE < DEBUG < INFO < WARN < ERROR

    Logback配置说明

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- scan:当该属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。 scanPeriod:设置监测配置文件是否修改的时间间隔,如果没有给出时间单位,默认单位是毫秒,默认的时间间隔为1分钟,当scan为true时,此属性生效 debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
    <configuration scan="true" scanPeriod="60 seconds" debug="false"> <!-- 定义日志的根目录 --> <property name="LOG_HOME" value="/app/log" /> <!-- 定义日志文件名称 --> <property name="appName" value="SkyTest"></property>
    <!-- ch.qos.logback.core.ConsoleAppender 表示控制台输出,     ch.qos.logback.core.FileAppender 输出到文件      ch.qos.logback.core.rolling.RollingFileAppender回滚 -->
    <!----------------------------------------------------------------------------------> <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
       <!--编码-->   <Encoding>UTF-8</Encoding>    <!--    日志输出格式:%d表示日期时间,%thread表示线程名,%-5level:级别从左显示5个字符宽度    %logger{50} 表示logger名字最长50个字符,否则按照句点分割。 %msg:日志消息,%n是换行符    -->    <layout class="ch.qos.logback.classic.PatternLayout">   <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>   </layout> </appender> <!----------------------------------------------------------------------------------> <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 --> <appender name="appLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">

       <!-- 过滤器,只记录WARN级别的日志 ,不常用-->
       <filter class="ch.qos.logback.classic.filter.LevelFilter">
           <level>ERROR</level>
           <onMatch>ACCEPT</onMatch>
           <onMismatch>DENY</onMismatch>
       </filter>
    <Encoding>UTF-8</Encoding>
    <!-- 指定日志文件的名称,<property> 有两个属性,name和value;其中name的值是变量的名称,value的值时变量定义的值。通过<property>定义的值会被插入到logger上下文中。 定义变量后,可以使“${}”来使用变量。 --> <file>${LOG_HOME}/${appName}.log</file>
    <!--     rollingPolicy回滚策略:    TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动。 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
         <!--     滚动时产生的文件的存放位置及文件名称 %d{yyyy-MM-dd}:按天进行日志滚动     %i:当文件大小超过maxFileSize时,按照i进行文件滚动       -->      <fileNamePattern>${LOG_HOME}/${appName}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>      <!--       可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每天滚动,      且maxHistory是365,则只保存最近365天的文件,删除之前的旧文件。注意,删除旧文件是,      那些为了归档而创建的目录也会被删除。      -->     <MaxHistory>365</MaxHistory>
            <!--      当日志文件超过maxFileSize指定的大小时,根据上面提到的%i进行日志文件滚动,注意此处配置SizeBasedTriggeringPolicy是无法实现按文件大小进行滚动的,
            必须配置timeBasedFileNamingAndTriggeringPolicy     -->
       <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">    <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy>
    <!--    日志输出格式:%d表示日期时间,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %logger{50} 表示logger名字最长50个字符,否则按照句点分割。 %msg:日志消息,%n是换行符 --> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n</pattern> </layout>
    </appender>

    <!----------------------------------------------------------------------------------> <!-- logger主要用于存放日志对象,也可以定义日志类型、级别 name:表示匹配的logger类型前缀,也就是包的前半部分 level:要记录的日志级别,包括 TRACE < DEBUG < INFO < WARN < ERROR additivity:是否向上级loger传递打印信息。默认是true。<loger>可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个logger。 --> <!-- hibernate logger --> <logger name="org.hibernate" level="error" />
    <!-- Spring framework logger --> <logger name="org.springframework" level="error" additivity="false"></logger> <logger name="com.creditease" level="info" additivity="true"> <appender-ref ref="appLogAppender" /> </logger> <!-- root与logger是父子关系,没有特别定义则默认为root,任何一个类只会和一个logger对应,有匹配的logger则为logger,没有则为默认的root --> <root level="info"> <appender-ref ref="stdout" /><!--stdouty与appender的name保持一致--> <appender-ref ref="appLogAppender" /> </root> <!-- show parameters for hibernate sql 专为 Hibernate 定制 --> <logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" /> <logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="DEBUG" /> <logger name="org.hibernate.SQL" level="DEBUG" /> <logger name="org.hibernate.engine.QueryParameters" level="DEBUG" /> <logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" /> <!--日志异步到数据库 --> <appender name="DB" class="ch.qos.logback.classic.db.DBAppender"> <!--日志异步到数据库 --> <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource"> <!--连接池 --> <dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource"> <driverClass>com.mysql.jdbc.Driver</driverClass> <url>jdbc:mysql://127.0.0.1:3306/databaseName</url> <user>root</user> <password>root</password> </dataSource> </connectionSource> </appender> </configuration>
    <!--
      <encoder>:对日志进行格式化。//都有
      <target>:字符串 System.out 或者 System.err ,默认 System.out //控制台
      <file>:被写入的文件名,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建,没有默认值。 //文件,回滚日志
      <append>:如果是 true,日志被追加到文件结尾,如果是 false,清空现存文件,默认是true。//文件,回滚日志
      <prudent>:如果是 true,日志会被安全的写入文件,即使其他的FileAppender也在向此文件做写入操作,效率低,默认是 false。//文件,回滚日志
      <rollingPolicy>:当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名。 //回滚日志
      <triggeringPolicy >: 告知 RollingFileAppender 合适激活滚动  //回滚日志
    -->
    

     logback-spring.xml:添加-spring后,日志框架就不直接加载日志的配置项,而是由SpringBoot解析加载,可以使用SpringBoot的高级Profile功能,假如没有-spring,那么由logback会直接加载

    6.log4j的配置(LOG4J.xml放在类路径下会自动加载)

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
     
    <log4j:configuration>
        <!--STDOUT表示输出  org.apache.log4j.ConsoleAppender 表示输出的类,这里表示输出到控制台-->
        <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
            <!--表达式输出的字符集-->
            <param name="Encoding" value="UTF-8"/>
            <!--org.apache.log4j.PatternLayout 对象和与之相关的格式化的日志记录信息转换模式,这里表示表达式-->
            <layout class="org.apache.log4j.PatternLayout">
                <!--ConversionPattern格式 -->
                <param name="ConversionPattern" value="%-5p %d{yyyy/MM/dd HH:mm:ss,SSS} %m  %c (%F:%L) 
    "/>
            </layout>
        </appender>
     
        <!--org.apache.log4j.ConsoleAppender(控制台)-->
        <!--org.apache.log4j.FileAppender(文件)-->
        <!--org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)-->
        <!--org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)-->
        <!--org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)-->
        <appender name="file" class="org.apache.log4j.FileAppender">
            <!--表达式输出的字符集-->
            <param name="Encoding" value="UTF-8"/>
            <!--Threshold=debug:指定日志消息的输出最低层次。-->
            <param name="Threshold" value="debug"/>
            <!--append:默认值是true,即将消息增加到指定文件中,false指将消息覆盖指定的文件内容-->
            <param name="append" value="true"/>
            <!--File指定消息输出到mylog.txt文件。-->
            <param name="File" value="D:/logs/log4j.log"/>
            <!--ImmediateFlush:默认值是true,意谓着所有的消息都会被立即输出。-->
            <param name="ImmediateFlush" value="true"/>
            <!--org.apache.log4j.PatternLayout 对象和与之相关的格式化的日志记录信息转换模式,这里表示表达式-->
            <layout class="org.apache.log4j.PatternLayout">
                <!--ConversionPattern格式
                %c: 输出日志信息所属的类目,通常就是所在类的全名
                %d: 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy/MM/dd HH:mm:ss,SSS},
                输出类似:2018/10/06 14:16:41,429
                %p: 输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL,
                %F: 输出日志消息产生时所在的文件名称
                %L: 输出代码中的行号
                "-"号指定左对齐。
                %m: 输出代码中指定的消息,产生的日志具体信息
                
      换行
                %r: 输出自应用启动到输出该log信息耗费的毫秒数
                -->
                <param name="ConversionPattern" value="%-5p %d{yyyy/MM/dd HH:mm:ss,SSS} %m  %c (%F:%L) 
    "/>
            </layout>
        </appender>
     
      <!--  <appender name="rolling" class="org.apache.log4j.FileAppender">
            其他参数
             在name="file"的基础上增加了如下两个参数
             MaxFileSize=200KB: 后缀可以是KB, MB 或者是 GB. 在日志文件到达该大小时,将会自动滚动,即将原来的内容移到mylog.log.1文件。
             MaxBackupIndex=5:指定可以产生的滚动文件的最大数。
        </appender>-->
     
       <!--
        properties与xml的配置类似,只是在properties中用的是点,而在xml中是节点
        # 应用于socket
        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 Factor 5
        log4j.appender.socket.layout=org.apache.log4j.PatternLayout
        log4j.appender.socket.layout.ConversionPattern=[%-5p] %d(%r) –> [%t] %l: %m %x %n
        # Log Factor 5 Appender
        log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
        log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000
        # 发送日志到指定邮件
        log4j.appender.mail=org.apache.log4j.net.SMTPAppender
        log4j.appender.mail.Threshold=FATAL
        log4j.appender.mail.BufferSize=10
        log4j.appender.mail.From = xxx@mail.com
        log4j.appender.mail.SMTPHost=mail.com
        log4j.appender.mail.Subject=Log4J Message
        log4j.appender.mail.To= xxx@mail.com
        log4j.appender.mail.layout=org.apache.log4j.PatternLayout
        log4j.appender.mail.layout.ConversionPattern=[%-5p] %d(%r) –> [%t] %l: %m %x %n
        # 应用于数据库
        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('=[%-5p] %d(%r) –> [%t] %l: %m %x %n')
        log4j.appender.database.layout=org.apache.log4j.PatternLayout
        log4j.appender.database.layout.ConversionPattern=[%-5p] %d(%r) –> [%t] %l: %m %x %n
    -->
        <!--指定包名下的输出级别-->
        <logger name="cn.mybaties.dao">
            <level value="debug"/>
        </logger>
     
        <!--STDOUT的所有的输出级别  fatal(致命错误) > error (错误) > warn (警告) > info(普通信
    息) > debug(调试信息)    如下为相应的name添加级别-->
        <root>
            <level value="warn"/>
            <appender-ref ref="STDOUT"/>
            <appender-ref ref="file"/>
        </root>
    </log4j:configuration>
    
  • 相关阅读:
    从读者角度来看Blog
    NDuiker项目第3天
    IssueVision的List控件源码分析
    测试一个网站的想法
    IssueVision的PaneCaption控件源码分析
    技术研究的时候不要忘了“集成创新”
    人脸识别活体检测之张张嘴和眨眨眼
    jsp>Session 小强斋
    jsp>Request对象 小强斋
    jsp>四种作用域 小强斋
  • 原文地址:https://www.cnblogs.com/gg128/p/9749395.html
Copyright © 2020-2023  润新知