• web项目日志记录方案


    一、概述

    1、采用slf4j作为日志API,采用logback作为日志输出工具,用slf4j桥接方式替换掉log4j和commons-logging。

    2、采用trace(追踪)、debug(调试)、info(信息)、warn(警告)、error(错误)、fatal(致命)共6种日志级别。

    3、采用dev(开发环境)、test(测试环境)、production(生产环境)等不同的日志配置,根据环境变量自动识别。

    4、特殊的记录,需要大批量写入日志文件,应该采用异步线程写文件。

    二、日志级别定义

        采用trace(追踪)、debug(调试)、info(信息)、warn(警告)、error(错误)、fatal(致命)共6种日志级别。

        log4j建议使用4种级别 :优先级 从高到低分别是 ERROR、WARN、INFO、DEBUG;如果添加了日志开关,那么会优先展示优先级别高的;

        如 : 在这里定义了INFO级别, 则应用程序中所有DEBUG级别的日志信息将不被打印出来。

    日志级别使用原则:

    1、fatal(致命错误)使用原则

    fatal为系统级别的异常,发生fatal错误,代表服务器整个或者核心功能已经无法工作了!!

    1)在服务器启动时就应该检查,如果存在致命错误,直接抛异常,让服务器不要启动起来(启动了也无法正常工作,不如不启动)。

    2)如果在服务器启动之后,发生了致命的错误,则记录fatal级别的错误日志,最好是同时触发相关的修复和告警工作(比如,给开发和维护人员发送告警邮件)。

    2、error(错误)使用原则

    error为功能或者逻辑级别的严重异常,发生error级别的异常,代表功能或者重要逻辑遇到问题、无法正常工作。

    3、warn(警告)使用原则

    warn用在某些逻辑非常规,发生了一些小故障但是没有大的影响,或者重要数据被修改,或者某些操作需要引起重视。

    4、info(信息)使用原则

    info用于记录一些有用的、关键的信息,一般这些信息出现得不频繁,只是在初始化的地方或者重要操作的地方才记录。

    5、debug(调试)使用原则

    debug用于记录一些调试信息,为了方便查看程序的执行过程和相关数据、了解程序的动态。

    6、trace(跟踪)使用原则

    trace用于记录一些更详细的调试信息,这些信息无需每次调试时都打印出来,只在需要更详细的调试信息时才开启。

    7、项目稳定运行时的日志量

    1)正常情况下,trace日志至少是debug日志的100倍,

    trace级别的日志量 : debug级别的日志量  >  100 : 1,

    也就是说trace日志非常多,debug日志相对较少。

    2)debug级别的日志量 : info级别的日志量 > 1000 : 1,

    也就是说正常情况下,info日志很少,只在部分重要位置会输出 info日志。

    3)error日志和warn日志,正常情况下,几乎为0,当出现异常时,error日志和warn日志量 也在可控范围,不会超过debug级别的最大日志量。

    三、日志输出(Appender)分类

    分为5个一般类: 

        FILE_EXCEPTION (异常日志,包括ERROR和WARN)

        FILE_APP (应用日志,包括当前应用package下面的日志和DEBUG级别以上的其他日志)

        FILE_INFO (普通信息日志)

        FILE_DEBUG (调试日志)

        FILE_TRACE(追踪日志)

        SYSOUT(控制台输出,可以包括以上所有日志)

    扩展类: 包括异步输出的日志,或者特殊业务日志。

    举例说明:

    假如 

    当前应用的 Main Package 为 cn.zollty.lightning

    ROOT_LEVEL为 trace,应用日志 LEVEL 为 debug

    有以下日志打印:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Logger loggerA = LoggerFactory.getLogger(cn.zollty.lightning.Tests.class);
    loggerA.trace("--------");
    loggerA.debug("--------");
    loggerA.info("--------");
    loggerA.warn("--------");
    loggerA.error("--------");
     
    Logger loggerB = LoggerFactory.getLogger(org.apache.kafka.Consumer.class);
    loggerB.trace("--------");
    loggerB.debug("--------");
    loggerB.info("--------");
    loggerB.warn("--------");
    loggerB.error("--------");

    那么,异常日志(FILE_EXCEPTION)输出的为:

    loggerA.warn("--------");

    loggerA.error("--------");

    loggerB.warn("--------");

    loggerB.error("--------");

    控制台(SYSOUT)输出日志的为;

    loggerA.debug("--------");

    loggerA.info("--------");

    loggerA.warn("--------");

    loggerA.error("--------");

    loggerB.trace("--------");

    loggerB.debug("--------");

    loggerB.info("--------");

    loggerB.warn("--------");

    loggerB.error("--------");

    应用日志(FILE_APP)输出的为:

    loggerA.debug("--------");

    loggerA.info("--------");

    loggerA.warn("--------");

    loggerA.error("--------");

    loggerB.info("--------");

    loggerB.warn("--------");

    loggerB.error("--------");

    2、历史日志文件

    异常日志(error和warn)最多保存 9000 M(生产,测试)

    app日志最多保存 9000 M (生产,测试)

    trace日志最多保存 1000 M (仅供测试用,一般不用)

    debug、info日志最多保存 5000 M(一般不用,用app日志就够了)

    四、各环境默认日志定义

    开发环境

    1)默认日志级别定义为:

        app包为TRACE级别。日志的ROOT Level为DEBUG级别。

    2)

    启用 System.out 控制台输出日志;

    启用error.log为错误和警告日志、app.log为应用日志(包括app包下的日志和其他INFO级别以上的日志)。

    测试环境

    1)默认日志级别定义为:

        app包为DEBUG级别。日志的ROOT Level为DEBUG级别。

    2)

    禁用 System.out 控制台输出日志;

    启用error.log为错误和警告日志、app.log为应用日志(包括app包下的日志和其他INFO级别以上的日志)。

    生产环境

    1)默认日志级别定义为:

        app包为DEBUG级别。日志的ROOT Level为INFO级别。

    2)

    禁用 System.out 控制台输出日志;

    启用error.log为错误和警告日志、app.log为应用日志(包括app包下的日志和其他INFO级别以上的日志)。

    五、根据环境自动选择日志配置(借助Logback)

    关键点1:使用logback的环境变量定义和读取功能

    例如下面的各种环境变量定义:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <!-- 部署的环境类型:dev、test、product -->
    <property name="DEPLOY_ENV" value="${deploy.env:-dev}" />
     
    <!-- 日志路径,这里是相对路径,web项目eclipse下会输出到当前目录./logs/下,如果部署到linux上的tomcat下,会输出到tomcat/logs/目录 下 -->
    <property name="LOG_HOME" value="${catalina.base:-.}/logs" />
     
    <!-- 日志文件大小,超过这个大小将被压缩 -->
    <property name="LOG_MAX_SIZE" value="100MB" />
    <!-- 日志输出格式 -->
    <property name="LOG_COMMON_PATTERN" value="%d{HH:mm:ss.SSS} [%thread] [%level] %logger - %msg%n" />
    <property name="LOG_DEV_PATTERN" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{48}:%line - %msg%n" />
     
    <!-- 主日志级别 -->
    <property name="ROOT_LEVEL" value="${log.root.level:-DEBUG}" />
     
    <!-- APP 日志级别 -->
    <property name="APP_LEVEL" value="${log.app.level:-TRACE}" />
    <!-- APP Package 前缀: cn.zollty.lightning -->
    <property name="APP_PACKAGE" value="cn.zollty.lightning" />

    其中 ${deploy.env:-dev} 代表的意思是,如果环境变量中没有 deploy.env,则使用默认值dev。

    一个小技巧:可以自定义类似下面这个类,在logback初始化之前,先设置变量的值:

    1
    <statusListener class="cn.zollty.commons.logbackext.InitConfigOnConsoleStatusListener" />

    这个类继承自ch.qos.logback.core.status.OnConsoleStatusListener。

    关键点2:使用logback的 if-then 条件语法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <root level="${ROOT_LEVEL}">
      <!-- Required: exception log -->
      <appender-ref ref="FILE_EXCEPTION"/>
      <!-- Required: app log  -->
      <appender-ref ref="FILE_APP"/>
     
      <if condition='p("DEPLOY_ENV").contains("dev")'>
        <then>
        <appender-ref ref="STDOUT" />
        </then>
      </if>
    </root>

    参考配置:

    logback.xml:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration scan="true" scanPeriod="60 seconds" debug="false">
     
      <statusListener class="cn.zollty.commons.logbackext.InitConfigOnConsoleStatusListener" />
     
      <!-- 部署的环境类型:dev、test、product -->
      <property name="DEPLOY_ENV" value="${deploy.env:-dev}" />
     
      <!-- 日志路径,这里是相对路径,web项目eclipse下会输出到当前目录./logs/下,如果部署到linux上的tomcat下,会输出到tomcat/logs/目录 下 -->
      <property name="LOG_HOME" value="${catalina.base:-.}/logs" />
       
      <!-- 日志文件大小,超过这个大小将被压缩 -->
      <property name="LOG_MAX_SIZE" value="100MB" />
      <!-- 日志输出格式 -->
      <property name="LOG_COMMON_PATTERN" value="%d{HH:mm:ss.SSS} [%thread] [%level] %logger - %msg%n" />
      <property name="LOG_DEV_PATTERN" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{48}:%line - %msg%n" />
     
      <!-- 主日志级别 -->
      <property name="ROOT_LEVEL" value="${log.root.level:-DEBUG}" />
     
      <!-- APP 日志级别 -->
      <property name="APP_LEVEL" value="${log.app.level:-TRACE}" />
      <!-- APP Package 前缀: cn.cstonline.zollty -->
      <property name="APP_PACKAGE" value="cn.zollty.lightning" />
       
      <include resource="includedConfig.xml"/>
       
      <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
          <pattern>${LOG_DEV_PATTERN}</pattern>
        </encoder>
      </appender>
       
      <appender name="FILTER-DATA" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/filter.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
          <fileNamePattern>${LOG_HOME}/filter/filter-%d{yyyy-MM-dd}-%i.log.zip</fileNamePattern>
          <maxHistory>90</maxHistory>
          <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <MaxFileSize>100MB</MaxFileSize>
          </TimeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
          <pattern>${LOG_COMMON_PATTERN}</pattern>
        </encoder>
      </appender>
       
      <appender name="ASYNC1" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="FILTER-DATA" />
      </appender>
       
      <include resource="special_log_level.xml"/>
     
      <logger name="${APP_PACKAGE}" level="${APP_LEVEL}" />
       
      <logger name="FILTER-LOGGER" level="${APP_LEVEL}" additivity="false">
        <appender-ref ref="ASYNC1" />
      </logger>
     
      <root level="${ROOT_LEVEL}">
        <!-- Required: exception log -->
        <appender-ref ref="FILE_EXCEPTION"/>
        <!-- Required: app log  -->
        <appender-ref ref="FILE_APP"/>
         
        <!-- Optional: show all debug or trace info -->
        <!-- <appender-ref ref="FILE_DEBUG"/> -->
        <!-- <appender-ref ref="FILE_TRACE"/> -->
         
        <if condition='p("DEPLOY_ENV").contains("dev")'>
          <then>
            <appender-ref ref="STDOUT" />
          </then>
        </if>
         
      </root>
     
    </configuration>

    includedConfig.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    <?xml version="1.0" encoding="UTF-8" ?>
     
    <included>
     
      <!-- WARN and ERROR -->
      <appender name="FILE_EXCEPTION" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
          <level>WARN</level>
        </filter>
        <file>${LOG_HOME}/error.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
          <!-- rollover daily -->
          <fileNamePattern>${LOG_HOME}/error/error-%d{yyyy-MM-dd}-%i.log.zip</fileNamePattern>
          <maxHistory>90</maxHistory>
          <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <!-- or whenever the file size reaches 100MB -->
            <MaxFileSize>${LOG_MAX_SIZE}</MaxFileSize>
          </TimeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
          <pattern>${LOG_COMMON_PATTERN}</pattern>
        </encoder>
      </appender>
     
      <!-- INFO or Greater -->
      <appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
          <level>INFO</level>
        </filter>
        <file>${LOG_HOME}/info.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
          <fileNamePattern>${LOG_HOME}/info/info-%d{yyyy-MM-dd}-%i.log.zip</fileNamePattern>
          <maxHistory>50</maxHistory>
          <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <MaxFileSize>${LOG_MAX_SIZE}</MaxFileSize>
          </TimeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
          <pattern>${LOG_COMMON_PATTERN}</pattern>
        </encoder>
      </appender>
     
      <!-- DEBUG or Greater-->
      <appender name="FILE_DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
          <level>DEBUG</level>
        </filter>
        <file>${LOG_HOME}/debug.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
          <fileNamePattern>${LOG_HOME}/debug/debug-%d{yyyy-MM-dd}-%i.log.zip</fileNamePattern>
          <maxHistory>50</maxHistory>
          <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <MaxFileSize>${LOG_MAX_SIZE}</MaxFileSize>
          </TimeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
          <pattern>${LOG_COMMON_PATTERN}</pattern>
        </encoder>
      </appender>
     
      <!-- TRACE and ALL -->
      <appender name="FILE_TRACE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/trace.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
          <fileNamePattern>${LOG_HOME}/trace/trace-%d{yyyy-MM-dd}-%i.log.zip</fileNamePattern>
          <maxHistory>10</maxHistory>
          <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <MaxFileSize>${LOG_MAX_SIZE}</MaxFileSize>
          </TimeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
          <pattern>${LOG_COMMON_PATTERN}</pattern>
        </encoder>
      </appender>
       
      <!-- (INFO or Greater) or logname prefix = ${APP_PACKAGE} -->
      <appender name="FILE_APP" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="cn.zollty.lightning.common.PackageOrThresholdFilter">
          <level>INFO</level>
          <prefix>${APP_PACKAGE}</prefix>
        </filter>
        <file>${LOG_HOME}/app.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
          <fileNamePattern>${LOG_HOME}/app/app-%d{yyyy-MM-dd}-%i.log.zip</fileNamePattern>
          <maxHistory>90</maxHistory>
          <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <MaxFileSize>${LOG_MAX_SIZE}</MaxFileSize>
          </TimeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
          <pattern>${LOG_COMMON_PATTERN}</pattern>
        </encoder>
      </appender>
     
    </included>

    special_log_level.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <?xml version="1.0" encoding="UTF-8" ?>
    <included>
     
      <logger name="org.apache.zookeeper.ClientCnxn" level="ERROR" />
      <logger name="org.apache.kafka.clients.consumer.internals.ConsumerCoordinator" level="INFO" />
      <logger name="kafka.producer.BrokerPartitionInfo" level="INFO" />
      <logger name="kafka.producer.async.ProducerSendThread" level="INFO" />
      <logger name="kafka.producer.async.DefaultEventHandler" level="INFO" />
      <logger name="org.apache.kafka.common.metrics.Metrics" level="INFO" />
      <logger name="org.apache.kafka.clients.Metadata" level="INFO" />
       
      <logger name="org.apache.kafka.clients.consumer.internals.AbstractCoordinator" level="INFO" />
      <logger name="org.apache.kafka.clients.consumer.internals.Fetcher" level="INFO" />
      <logger name="org.apache.kafka.clients.NetworkClient" level="INFO" />
       
    </included>

    也可以把变量定义到properties文件中,本地就放在 

    src/resources/conf/logback_val.properties

    服务器上放在

    ${catalina.base}/conf/logback_val.properties

    配置如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration scan="true" scanPeriod="60 seconds" debug="false">
     
      <if condition='isDefined("catalina.base")'>
        <then>
          <property file="${catalina.base}/conf/logback_val.properties" />
        </then>
        <else>
          <property resource="./conf/logback_val.properties" />
        </else>
      </if>
       
      ...

    logback_val.properties:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # u90E8u7F72u7684u73AFu5883u7C7Bu578BuFF1Adevu3001testu3001product
    deploy.env=dev
    # u4E3Bu65E5u5FD7u7EA7u522B
    log.root.level=DEBUG
    # APP u65E5u5FD7u7EA7u522B
    log.app.level=TRACE
    # Kafka LogStash u9009u62E9u4F7Fu7528 value= "yes" or "no"
    log.use.logstash=yes
    # LogStash Kafka URL
    log.logstash.kafka=172.16.1.164:9092,172.16.1.165:9092,172.16.1.166:9092

    log4j中进行过滤的方法 :

    log4j中log.isDebugEnabled(), log.isInfoEnabled()和log.isTraceEnabled()作用 :
      1、项目在应用log4j打印Debug,Info和Trace级别的log时需要加上对应的三个方法进行过滤,代码如下:
    		if (log.isDebugEnabled()) {
    		    log.debug(" From: " + req.getFrom().toString() + 
    		                  " To: " + req.getTo().toString() + 
    		                  " CallId: " + req.getCallId() + 
    		                  " msg:" + msg);
    		}
    	其作用是因为Debug,Info和Trace一般会打印比较详细的信息,而且打印的次数较多,如果我们不加log.isDebugEnabled()等
    	进行预先判断,当系统loglevel设置高于Debug或Info或Trace时,虽然系统不会答应出这些级别的日志,但是每次还是会拼接
    	参数字符串,影响系统的性能。
      2、错误的优化方法
    	部分编码人员因为不了解机制,从代码复用性和简洁性而言定义如下函数来封装
    	    private void debug(String msg) {
    	        if (log.isDebugEnabled()) {
    	            log.debug(msg);
    	        }
    	    }
    	其实这种封装方式是错误的,因为当系统中调用debug(msg)函数还是出现字符串的拼接。
     
    结论:这3个方法是对项目的优化方法,加这个方法目的在于如果代码中存在连接字符串的情况,打印信息时会出现太多的拼接字符串影响
           系统性能。如果系统中是固定字符串加不加都可以。  
    

      

    log4j的使用:

    ##define an appender named console
    log4j.appender.console=org.apache.log4j.ConsoleAppender
    #The Target value is System.out or System.err(out kong zhi tai xian shi wei hei se;err kong zhi tai xian shi hong se)
    log4j.appender.console.Target=System.out
    #set the layout type of the apperder
    log4j.appender.console.layout=org.apache.log4j.PatternLayout
    #set the layout format pattern(ri zhi ge shi)
    log4j.appender.console.layout.ConversionPattern=[%-5p][%d{yyyy-MM-dd HH:mm:ss}] %c %L %m%n
    
    
    ##define an appender named file(shu chu dao wen jian)
    log4j.appender.file=org.apache.log4j.FileAppender
    #define the file path and name
    log4j.appender.file.File=d:/logfile.txt
    #set the layout type of the apperder
    log4j.appender.file.layout=org.apache.log4j.PatternLayout
    #set the layout format pattern
    log4j.appender.file.layout.ConversionPattern=[%-5p][%d{yyyy-MM-dd HH:mm:ss}] %c %L %m%n
    
    
    ##define an appender named rollfile(shu chu dao wen jian,dan da dao zhi ding nei cun,hui chong xin cheng cheng yi ge wen jian)
    log4j.appender.rollfile=org.apache.log4j.RollingFileAppender
    #define the file path and name
    log4j.appender.rollfile.File=d:/logrollfile.txt
    #set the log's size(zhi ding ri zhi wen jian da xiao)
    log4j.appender.rollfile.MaxFileSize=10KB
    #set the layout type of the apperder
    log4j.appender.rollfile.layout=org.apache.log4j.PatternLayout
    #set the layout format pattern
    log4j.appender.rollfile.layout.ConversionPattern=[%-5p][%d{yyyy-MM-dd HH:mm:ss}] %c %L %m%n
    
    
    ##define a logger(zhi ding ri zhi ji bie he shi yong na xie zui jia qi)
    #log4j.logger.全限定性类名或接口名=INFO,console,file,rollfile
    log4j.rootLogger=INFO,console,file,rollfile
    

      

    log4j2的使用:

    <?xml version="1.0" encoding="UTF-8"?>
    <-- status 是否输出日志中的日志(引入了日志的jar包) -->
    <configuration status="OFF">
    	<appenders>
    	    <-- SYSTEM_OUT/SYSTEM_ERR -->
    		<Console name="myConsole" target="SYSTEM_OUT">
    			<PatternLayout pattern="[%-5p][%d{yyyy-MM-dd HH:mm:ss}] [%c %L] %m%n" />
    		</Console>
    		<-- append="true" 表示追加,不删除之前的日志;false是会删除之前的日志	 -->
    		<File name="myLogFile" fileName="log/test.log" append="true">
                <PatternLayout pattern="[%-5p][%d{yyyy-MM-dd HH:mm:ss}] [%c %L] %m%n"/>
            </File>
    		<-- logs/app.log 项目根目录log -->
            <RollingFile name="myRollingFile" fileName="logs/app.log"
    					 <-- 按月来管理日志 log.gz 的.gz为压缩格式 -->
                         filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
    					 
    					 <--
    					 按日来管理日志  filePattern="logs/$${date:yyyy-MM-dd}/app-%d{MM-dd-yyyy}-%i.log.gz"
    					 -->
    					
    					 
                <PatternLayout pattern="[%-5p][%d{yyyy-MM-dd HH:mm:ss}] [%c %L] %m%n"/>
    			<-- 日志文件大小,超出这个空间,会重新生成一个文件 -->
                <SizeBasedTriggeringPolicy size="1KB"/>
            </RollingFile>
    	</appenders>
    	
    	<loggers>
    		<!-- 
    		<logger name="全限定类名或接口名" level="info">
    			<appender-ref ref="myConsole" />
    		</logger>
    		 -->
    		<-- 日志输出级别 -->
    		<root level="info">
    			<-- 使用那些追加器 -->
    			<appender-ref ref="myConsole" />
    			<!-- <appender-ref ref="myLogFile" /> -->
    			<!-- <appender-ref ref="myRollingFile" /> -->
    		</root>
    	</loggers>
    	
    </configuration>
    

      

    参考资料:

    http://logback.qos.ch/manual/configuration.html#conditional

  • 相关阅读:
    ARM 浮点运算
    手机微硬盘读取速度>50MB/s eMMC技术浅析
    Chrome 浏览器跨域和安全访问问题 使用 chrome的命令行标记:disable-web-security 参数联调线上数据
    Vue学习手札
    使用MouseWithoutBordersSetup共享鼠标键盘教程
    java使用POI获取sheet、行数、列数
    基于Spring MVC实现基于form表单上传Excel文件,批量导入数据
    org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML.
    [MYSQL]时间毫秒数转换
    springmvc 传递和接收数组参数
  • 原文地址:https://www.cnblogs.com/qqyong123/p/8579037.html
Copyright © 2020-2023  润新知