• 007-log-log4j2、slf4j+log4j2


     一、概述

      而log4j2的性能无论在同步日志模式还是异步日志模式下都是最佳的.

      根本原因在于log4j2使用了LMAX, 一个无锁的线程间通信库代替了, logback和log4j之前的队列. 并发性能大大提升,

      区别于log4j存在天然缺陷:

      1. log4j采用同步输出模式,当遇到高并发&日志输出过多情况,可能导致线程阻塞,消耗时间过大
      2. log4j无法实现自动删除按照日期产生的日志,现有项目都采用定时脚本删除日志。

      通过调研,log4j2采用异步输出,并且能通过配置实现自动删除日志。

    关于log4j2的新特性

    1. 丢数据这种情况少,可以用来做审计功能。而且自身内部报的exception会被发现,但是logback和log4j不会。
    2. log4j2使用了disruptor技术,在多线程环境下,性能高于logback等10倍以上。
    3. (garbage free)之前的版本会产生非常多的临时对象,会造成GC频繁,log4j2则在这方面上做了优化,减少产生临时对象。尽可能少的GC
    4. 利用插件系统,使得扩展新的appender,filter,layout等变得容易,log4j不可以扩展 插件????
    5. 因为插件系统的简单性,所以在配置的时候,可以不用具体指定所要处理的类型。class
    6. 可以自定义level
    7. Java 8 lambda support for lazy logging
    8. Support for Message objects
    9. 对filter的功能支持的更强大
    10. 系统日志(Syslog)协议supports both TCP and UDP
    11. 利用jdk1.5并发的特性,减少了死锁的发生。
    12. Socket LogEvent SerializedLayout
    13. 支持kafka queue

    1.1、pom依赖

            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-core</artifactId>
                <version>2.11.1</version>
            </dependency>
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-api</artifactId>
                <version>2.11.1</version>
            </dependency>

    log4j只需要引入一个jar包即可1.2.17,而log4j 2则是需要2个核心,log4j和log4j 2的包路径是不同的,Apache为了区分,包路径都更新了

    1.2、基础配置

    在classpath或者resources下增加log4j2.xml配置即可

    <?xml version="1.0" encoding="UTF-8"?>
    <!--设置log4j2的自身log级别为warn-->
    <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
    <!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,
        当设置成trace时,你会看到log4j2内部各种详细输出-->
    <!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
    <configuration status="warn" monitorInterval="30">
        <!--全局参数-->
        <Properties>
            <Property name="logPath">log</Property>
        </Properties>
        <!--先定义所有的appender-->
        <appenders>
            <!--这个输出控制台的配置-->
            <console name="Console" target="SYSTEM_OUT">
                <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}-%t] [%p] - %l - %m%n"/>
            </console>
         <!--文件输出,-->
            <RollingFile name="RollingFileInfo" fileName="${logPath}/info.log"
                         filePattern="${logPath}/info_%d{yyyy-MM-dd}.log">
                <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}-%t] [%p] - %l - %m%n"/>
                <Policies>
                    <!--按照filePattern 时间单位 interval 间隔生成文件-->
                    <TimeBasedTriggeringPolicy modulate="true" interval="1"/>
                </Policies>
            </RollingFile>
    
        </appenders>
        <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
        <loggers>
            <!--过滤掉spring和hibernate的一些无用的debug信息-->
            <logger name="org.springframework" level="INFO"></logger>
            <logger name="org.elasticsearch" level="INFO"></logger>
            <logger name="com.jd.jsf.gd" level="warn"></logger>
            <logger name="org.mybatis" level="INFO"></logger>
            <logger name="org.apache.ibatis.logging.jdbc" level="warn"></logger>
    
            <!-- 将业务dao接口填写进去,并用控制台输出即可 -->
            <logger name="com.github.bjlhx15.data.repository" level="debug" additivity="false">
                <appender-ref ref="Console"/>
                <appender-ref ref="RollingFileInfo"/>
            </logger>
    
            <root level="info">
                <appender-ref ref="Console"/>
                <appender-ref ref="RollingFileInfo"/>
            </root>
        </loggers>
    
    </configuration>

    1.3、程序使用

    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    public class ApplicationMain {
        private static Logger logger = LogManager.getLogger(ApplicationMain.class);
    
        public static void main(String[] args) {
            // 记录debug级别的信息
            logger.debug("This is debug message.");
            // 记录info级别的信息
            logger.info("This is info message.");
            // 记录error级别的信息
            logger.error("This is error message.");
        }
    }

    二、配置详解

    2.1、配置文件

    2.1.1.关于配置文件的名称以及在项目中的存放位置

        log4j 2.x版本不再支持像1.x中的.properties后缀的文件配置方式,2.x版本配置文件后缀名只能为".xml",".json"或者".jsn".

        系统选择配置文件的优先级(从先到后)如下:

          (1).classpath下的名为log4j2-test.json 或者log4j2-test.jsn的文件.

          (2).classpath下的名为log4j2-test.xml的文件.

          (3).classpath下名为log4j2.json 或者log4j2.jsn的文件.

          (4).classpath下名为log4j2.xml的文件.

         我们一般默认使用log4j2.xml进行命名。如果本地要测试,可以把log4j2-test.xml放到classpath,而正式环境使用log4j2.xml,则在打包部署的时候不要打包log4j2-test.xml即可。

    2.1.2.缺省默认配置文件

        <?xml version="1.0" encoding="UTF-8"?>  
        <configuration status="OFF">  
            <appenders>  
                <Console name="Console" target="SYSTEM_OUT">  
                    <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>  
                </Console>  
            </appenders>  
            <loggers>  
                <root level="error">  
                    <appender-ref ref="Console"/>  
                </root>  
            </loggers>  
        </configuration>

    2.1.3.配置文件节点解析    

    (1).根节点Configuration有两个属性:status和monitorinterval,有两个子节点:Appenders和Loggers(表明可以定义多个Appender和Logger).

      status用来指定log4j本身的打印日志的级别.

      monitorinterval用于指定log4j自动重新配置的监测间隔时间,单位是s,最小是5s.

    (2).Appenders节点,常见的有三种子节点:Console、RollingFile、File.

    a、Console:节点用来定义输出到控制台的Appender.

        name:指定Appender的名字.

        target:SYSTEM_OUT 或 SYSTEM_ERR,一般只设置默认:SYSTEM_OUT.

        PatternLayout:输出格式,不设置默认为:%m%n.

    b、File:节点用来定义输出到指定位置的文件的Appender.

        name:指定Appender的名字.

        fileName:指定输出日志的目的文件带全路径的文件名.

        PatternLayout:输出格式,不设置默认为:%m%n.

    c、RollingFile节点用来定义超过指定大小自动删除旧的创建新的的Appender。rollover 表示的是当日志文件大小满足指定大小后,就生成一个新的文件的过程。

        RollingFileAppender是一个OutputStreamAppender,它(会把日志)写入到filename参数命名的文件中,并且会根据TriggeringPolicyRolloverPolicyrollover(rolls the file over)。RollingFileAppender会使用RollingFileManager(继承OutputStreamManager)来实际执行文件的I/O和执行rollover。尽管不能共享来做不同配置的RolloverFileAppenders,但是如果Manager可以访问的话,那么RolloverFileAppenders可以(进行共享)。 

        例如:在一个servlet容器中的两个web应用程序,他们有自己的配置,如果他们Log4j是共用一个类加载器(ClassLoader)那么就可以安全的写入到一个文件中。

        RollingFileAppender 需要TriggeringPolicyRolloverStrategytriggering policy决定是否应该执行rollover的操作,而RolloverStrategy定义了应该如何完成rollover。如果RolloverStrategy没有配置的话,RollingFileAppender将使用DefaultRolloverStrategy。从log4j2.5版本开始,在DefaultRolloverStrategy中配置的自定义删除操作在rollover时将被执行。 
    从2.8版本开始,如果在DirectWriteRolloverStrategy中没有配置文件名,将使用DefaultRolloverStrategy进行替换。

        RollingFileAppender不支持文件锁的。

      参数概述

    参数名类型描述
    append boolean  默认为true,记录追加到文件的最后,否则就先清除以前的记录再写入
    bufferedIO boolean 默认true,记录将会写入到缓存区,当缓存区满的时候,就会写入磁盘。或者如果设置immediateFlush将会立即写入。文件锁定不能和bufferedIO一起使用。
    bufferSize int 当bufferedIO设置为true是,默认是8192 bytes
    createOnDemand boolean 默认为false,该appender按需创建文件,当日志事件通过所有的filters并且通过路由指向了该appender,该appender仅仅创建该文件
    filter Filter 过滤器决定事件是否应该由这个Appender来处理。通过使用CompositeFilter来使用多个Filter
    fileName String 要写入的文件的名称。如果文件或其父目录不存在,它们都将被创建出来,指定输出日志的目的文件带全路径的文件名.
    filePattern String

    压缩日志文件的文件名的模式。该模式的格式取决于所使用的RolloverPolicyDefaultRolloverPolicy将接受兼容SimpleDateFormat的日期/时间模式和/或者%i(代表整数计数器)。

    这个模式也支持运行时插值,所以任何的查找( eg:DateLookup)都可以包含在模式中

    immediateFlush boolean

    默认为true,每次写入都会执行flush。这可以保证每次数据都被写入磁盘,但是会影响性能。在同步的loggers中每次写入执行flush,那就非常有用。

    异步loggers和appenders将会在一系列事件结束后自动执行flush,即使设置为false。这也保证了数据写入到磁盘而且很高效

    layout Layout 这个Layout用于格式化LogEvent.如果没有提供默认的layout,默认为layout模式为%m%n
    name String 该Appender名称
    policy【Policies】 TriggeringPolicy 用于决定是否发生rollover的策略
    strategy RolloverStrategy 用于决定压缩文件的名称和路径
    ignoreExceptions boolean 默认为true,遇到异常时,会将事件追加到内部日志并忽略它。设置false时,异常会传递给调用者,当这个appender被FailoverAppender包裹时,必须设置为false

        c.1、PatternLayout

          输出格式,不设置默认为:%m%n.具体含义桶log4j意义一致:002-log-log4j

    <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}-%t] [%p] - %l - %m%n"/>

        c.2、【Policies】Triggering Policies以下是Policies子节点

          c.2.1、Composite Triggering Policy【组合使用】

            Composite Triggering Policy组合了多个triggering policies,如果配置的策略中的任何一个返回true,则返回true。CompositeTriggeringPolicy简单的通过在policies元素包裹其他的policies来配置。 

            例如,以下XML片段定义了当JVM启动时,当日志大小达到二十兆字节以及当前日期与日志的开始日期不匹配时滚动日志的策略。

    <Policies> <OnStartupTriggeringPolicy /> <SizeBasedTriggeringPolicy size="20 MB" /> <TimeBasedTriggeringPolicy /> </Policies>

          c.2.2、Cron Triggering Policy【基于cron表达式的CronTriggeringPolicy触发rollover。】

          CronTriggeringPolicy 参数

    参数名称类型描述
    schedule String cron表达式。该表达式和Quartz调度所允许的表达式相同,有关表达式的完整描述,请参阅CronExpression
    evaluateOnStartup boolean 在启动时,将根据文件的最后修改时间戳评估cron表达式。如果cron表达式表示在该时间和当前时间之间应该发生rollover,则文件将立即rollover

          c.2.3、OnStartup Triggering Policy【程序启动时候执行一次rollover,如果日志文件比当前jvm启动时间更早以及满足或者超过最小文件的大小就会触发rollover】

          OnStartupTriggeringPolicy 参数说明:

    参数名称类型描述
    minSize           long         文件必定发生rollover操作的最小尺寸。要是大小为0的话,那么无论文件大小是多少都将引起rollover。默认值为1,这将阻止空文件发送rollover

          c.2.4、SizeBased Triggering Policy【一旦文件大小达到指定大小后,就会发送rollover。 单位可以使KB、MB、GB】

    <SizeBasedTriggeringPolicy size="200 MB"/>

          c.2.5、TimeBased Triggering Policy【按照filePattern 时间单位 interval 间隔生成文件】

          该策略接受一个interval属性和modulate布尔属性。其中interval属性表示的是,基于时间模式应该发送rollover的频率。

          TimeBasedTriggeringPolicy参数说明:

    参数名称类型描述
    interval  integer 根据日期格式中最具体的时间单位来决定应该多久发生一次rollover。例如,在日期模式中小时为具体的时间单位,那么每4小时会发生4次rollover,默认值为1
    modulate boolean 表示是否调整时间间隔以使在时间间隔边界发生下一个rollover。例如:假设小时为具体的时间单元,当前时间为上午3点,时间间隔为4,第一次发送rollover是在上午4点,接下来是上午8点,接着是中午,接着是下午4点等发生。
    maxRandomDelay integer 表示随机延迟翻转的最大秒数。默认情况下,该值为0表示没有延迟。此设置在将多个应用程序配置为同时翻转日志文件的服务器上非常有用,并且可以跨时间分担这样做的负担。

          c.3、Rollover Strategies

            c.3.1、DefaultRolloverStrategy

            默认的rollover strategy接受一个日期/时间模式和一个整数,其中这个整数,是RollingFileAppender本身指定的filePattern属性。如果date/time模式存在的话,它将会替换当前日期和时间的值。如果这个模式包含整数的话,它将会在每次发生rollover时,进行递增。如果模式同时包含date/time和整数,那么在模式中,整数会递增直到结果中的data/time模式发生改变。如果文件模式是以".gz", ".zip", ".bz2", ".deflate", ".pack200", or ".xz"结尾的,将会与后缀相匹配的压缩方案进行压缩文件。格式为:bzip2, Deflate, Pack200 和 XZ需要Apache Commons Compress,此外,XZ需要XZ for Java 
            该模式还可以包含可以在运行时解析的查找引用,如下面的示例所示: 
            默认的rollover策略支持三种增加计数的方式。第一种叫做:fixed window策略。为了说明它的工作原理,假设min属性设置为1,max属性设置为3,文件名为“foo.log”,文件名模式为:foo-%i.log。

    rollover次数输出的目标压缩的日志文件描述
    0 foo.log - 所有的日志都输出到初始文件中
    1 foo.log foo-1.log 在第一次rollover时,foo.log会被重命名为foo-1.log。同时会创建一个新的foo.log并开始写入。
    2 foo.log foo-1.log, foo-2.log 在第二次发生rollover时,foo-1.log会重命名为foo-2.log并且foo.log会重命名为foo-1.log。同时会创建一个新的foo.log并开始写入。
    3 foo.log foo-1.log, foo-2.log, foo-3.log 在第三次发生rollover时,foo-2.log会重命名为foo-3.log。foo-1.log重命名为foo-2.log,foo.log会重命名为foo-1.log。同时会创建一个新的foo.log并开始写入。
    4 foo.log foo-1.log, foo-2.log, foo-3.log 在第四次和随后的rollover时,foo-3.log会被删除,foo-2.log重命名为foo-3.log。foo-1.log重命名为foo-2.log。foo.log重命名为foo-1.log。后面同理

            相比之下,当 fileIndex属性设置了max,其他设置和上面相同,将执行以下操作:

    rollover次数输出的目标压缩的日志文件描述
    0 foo.log                       - 所有的日志都输出到初始文件中
    1 foo.log foo-1.log 在第一次rollover时,foo.log会被重命名为foo-1.log。同时会创建一个新的foo.log并开始写入。
    2 foo.log foo-1.log foo-2.log 在第二次rollover时,foo.log重命名为foo-2.log。同时会创建一个新的foo.log并开始写入。
    3 foo.log foo-1.log foo-2.log foo-3.log 在第三次发生rollover时,fool.log重命名为foo-3.log,同时会创建一个新的foo.log并开始写入。
    4 foo.log foo-1.log foo-2.log foo-3.log 在第四次和随后的rollover时,foo-1.log会被删除,foo-2.log重命名为foo-1.log,foo-3.log重命名为foo-2.log,foo.log重命名为foo-3.log。同时会创建一个新的foo.log并开始写入。

              最后,从2.8版本开始,如果fileIndex属性设置为nomax,那么最大和最小值,都将会被忽略掉,文件编号将从1开发增加,并且每次rollover时递增都从编码最大开始(项目于max效果),而且没有文件数的限制。

            DefaultRolloverStrategy参数

    参数名称类型描述
    fileIndex String 如果设置了max(默认就是),文件索引(编号)高的比低的更 新些。如果设置min,文件重命名将遵循Fixed Window策略
    min integer 计数器的最小值。默认值为1。
    max integer 计数器的最大值。一旦达到这个值,旧的档案将在随后的rollover中被删除。
    compressionLevel integer 设置压缩级别0-9,其中0=无,1=最佳速度,通过9=最佳压缩。只适用于ZIP文件。
    tempCompressedFilePattern String 压缩期间存档日志文件的文件名模式。

          c.3.2、DirectWrite Rollover Strategy

            会将日志事件会直接写入文件模式表示的文件中去。使用这个策略不会执行文件重命名。如果基于大小的触发策略导致在指定的时间段内写入多个文件,则它们将从一个编号开始,并持续递增,直到发生基于时间的rollover。 
    警告:如果文件模式里有压缩的后缀,那么当应用程序关闭时,当前文件将不被压缩。此外,如果时间变化使得文件模式不再匹配当前文件,则它也不会在启动时被压缩。

            DirectWriteRolloverStrategy 参数

    参数名称类型描述
    maxFiles  String 在与文件模式(file pattern)匹配的时间段内允许的最大文件数。如果这个数字被突破了,则最旧的文件将被删除。如果指定了,那么这个值必须大于1。如果值小于零或省略,则文件数不受限制。
    compressionLevel integer 设置压缩级别0-9,其中0=无,1=最佳速度,通过9=最佳压缩。只适用于ZIP文件。

            示例一、它使用RollingFileAppender同时具有基于时间和大小的触发策略,将在同一天(1-7)创建最多7个存档,这些存档存储在基于当前年份和月份的目录中,并将使用gzip压缩每个存档:

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <RollingFile name="RollingFile" fileName="logs/app.log"
                     filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
          <PatternLayout>
            <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
          </PatternLayout>
          <Policies>
            <TimeBasedTriggeringPolicy />
            <SizeBasedTriggeringPolicy size="250 MB"/>
          </Policies>
        </RollingFile>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="RollingFile"/>
        </Root>
      </Loggers>
    </Configuration>

            示例二、显示一个翻转策略,在删除之前最多可保留20个文件。

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <RollingFile name="RollingFile" fileName="logs/app.log"
                     filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
          <PatternLayout>
            <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
          </PatternLayout>
          <Policies>
            <TimeBasedTriggeringPolicy />
            <SizeBasedTriggeringPolicy size="250 MB"/>
          </Policies>
          <DefaultRolloverStrategy max="20"/>
        </RollingFile>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="RollingFile"/>
        </Root>
      </Loggers>
    </Configuration>

          示例三、它使用RollingFileAppender同时具有基于时间和大小的触发策略,将在同一天(1-7)创建最多7个存档,这些存档基于当前年份和月份存储在目录中,并将使用gzip压缩每个存档,并且当小时可被6整除时将每6小时滚动一次:

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <RollingFile name="RollingFile" fileName="logs/app.log"
                     filePattern="logs/$${date:yyyy-MM}/app-%d{yyyy-MM-dd-HH}-%i.log.gz">
          <PatternLayout>
            <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
          </PatternLayout>
          <Policies>
            <TimeBasedTriggeringPolicy interval="6" modulate="true"/>
            <SizeBasedTriggeringPolicy size="250 MB"/>
          </Policies>
        </RollingFile>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="RollingFile"/>
        </Root>
      </Loggers>
    </Configuration>

            示例四、配置使用RollingFileAppender同时具有基于cron和size的触发策略,并直接写入无限数量的归档文件。cron触发器每小时导致翻转,而文件大小限制为250MB:

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <RollingFile name="RollingFile" filePattern="logs/app-%d{yyyy-MM-dd-HH}-%i.log.gz">
          <PatternLayout>
            <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
          </PatternLayout>
          <Policies>
            <CronTriggeringPolicy schedule="0 0 * * * ?"/>
            <SizeBasedTriggeringPolicy size="250 MB"/>
          </Policies>
        </RollingFile>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="RollingFile"/>
        </Root>
      </Loggers>
    </Configuration>

            示例五、与上一个相同,但将每小时保存的文件数限制为10:

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <RollingFile name="RollingFile" filePattern="logs/app-%d{yyyy-MM-dd-HH}-%i.log.gz">
          <PatternLayout>
            <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
          </PatternLayout>
          <Policies>
            <CronTriggeringPolicy schedule="0 0 * * * ?"/>
            <SizeBasedTriggeringPolicy size="250 MB"/>
          </Policies>
          <DirectWriteRolloverStrategy maxFiles="10"/>
        </RollingFile>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="RollingFile"/>
        </Root>
      </Loggers>
    </Configuration>

        c.3.3、日志存档保留策略:Delete on Rollover

          log4j-2.5开始引入了删除操作,使得用户更有效的的控制在rollover时间内删除文件,而不是使用DefaultRolloverStrategy max属性进行删除。删除操作允许用户配置一个或多个条件,选择要删除相对于基本目录的文件。 

          注意:删除任何文件这是允许的操作。不仅仅是rollover时的文件。所以使用这个操作时,一定要小心。使用testMode参数可以测试您的配置,而不会意外删除错误的文件。

    参 数名称

    类型描述
    basePath  String 必参。从哪里扫描要删除的文件的基本路径。
    maxDepth int

    要访问的目录的最大级别数。值为0表示仅访问起始文件(基本路径本身),除非被安全管理者拒绝。

    Integer.MAX_VALUE的值表示应该访问所有级别。默认为1,意思是指定基本目录中的文件。

    followLinks boolean 是否遵循符号链接默认值为false。
    testMode boolean 默认false。如果为true,文件将不会被删除,而是将信息打印到info级别的status logger,可以利用这个来测试,配置是否和我们预期的一样
    pathSorter PathSorter 一个实现了PathSorter接口的插件在选择删除文件前进行排序。默认是最近修改的文件排在前面
    pathConditions PathCondition[]

    如果没有指定ScriptCondition,则为必需。一个或多个PathCondition元素。

    如果指定了多个条件,在删除之前,他们需要接受全部的路径。条件是可以嵌套的,在这种情况下,只有在外部路径被接受的情况下,才会去评估内部路径。

    如果条件没有嵌套,则可以按照任何顺序去评估。条件也可以通过IfAllIfAnyIfNot组合复合条件。他们对于的是AND、OR、NOT

    用户可以创建自定义条件或使用内置条件:

    IfFileName:接受路径(相对于基本路径)与正则表达式或glob匹配的文件。

    IfLastModified:接受与指定持续时间相同或更早的文件。

    IfAccumulatedFileCount :在file tree walk期间超过一些计数阈值后接受路径。

    IfAccumulatedFileSize:在file tree walk期间超过累积文件大小阈值后接受路径。

    ifAll:如果所有嵌套条件都接受它(逻辑与),则接受路径。嵌套条件可以按任何顺序进行评估。

    IfAny:如果其中一个嵌套条件接受(OR或OR),则接受路径。嵌套条件可以按任何顺序进行评估。

    IfNot:如果嵌套条件不接受(逻辑NOT),则接受路径。

    scriptCondition ScriptCondition

    如果没有指定PathConditions,则为必需。指定脚本的ScriptCondition元素。

    ScriptCondition应包含一个Script,ScriptRef或ScriptFile元素,用于指定要执行的逻辑。

    有关配置ScriptFiles和ScriptRefs的更多示例,请参阅ScriptFilter文档。该脚本传递了许多参数,

    包括在基本路径下找到的路径列表(最多为maxDepth),并且必须返回具有要删除路径的列表。

          IfFileName 条件参数:

    参数名称类型描述
    glob String 如果regex没有指定的话,则必须。使用类似于正则表达式但是又具有更简单的有限模式语言来匹配相对路径(相对于基本路径)
    regex String 如果glob没有指定的话,则必须。使用由Pattern类定义的正则表达式来匹配相对路径(相对于基本路径)
    nestedConditions PathCondition[] 一组可选的嵌套PathConditions如果存在任何嵌套条件,则在它们删除文件之前,必须都接受。仅当外部条件接受文件(如果路径名称匹配)时,才会评估嵌套条件。

          IfLastModified条件参数:

    参数名称类型描述
    age String 必须。指定持续时间duration。该条件接受比指定持续时间更早或更旧的文件。
    nestedConditions PathCondition[] 一组可选的嵌套PathConditions如果存在任何嵌套条件,则在它们删除文件之前,必须都接受。仅当外部条件接受文件(如果文件足够老)时,才会评估嵌套条件。

          IfAccumulatedFileCount 条件参数

    参数名称类型描述
    exceeds int 必须。将要删除文件的计数阈值。也就是需要保留的文件数。
    nestedConditions PathCondition[] 一组可选的嵌套PathConditions如果存在任何嵌套条件,则在它们删除文件之前,必须都接受。仅当外部条件接受文件(如果超过阈值计数)时,才会评估嵌套条件。

          IfAccumulatedFileSize 条件参数

    参数名称类型描述
    exceeds String 必须。将删除文件累计阀值的大小。大小可以指定字节。后缀可以是KB, MB or GB例如:20MB。也就是要保留最接近该值大小的文件。
    nestedConditions PathCondition[] 一组可选的嵌套PathConditions如果存在任何嵌套条件,则在它们删除文件之前,必须都接受。仅当外部条件接受文件(如果超过了阈值累积文件大小)时,才会评估嵌套条件。

          示例一、它使用RollingFileAppender和cron触发策略配置为每天午夜触发。档案存储在基于当前年份和月份的目录中。在转存时删除基本目录下与“* / app - * .log.gz”glob匹配且60天或更早的所有文件。

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Properties>
        <Property name="baseDir">logs</Property>
      </Properties>
      <Appenders>
        <RollingFile name="RollingFile" fileName="${baseDir}/app.log"
              filePattern="${baseDir}/$${date:yyyy-MM}/app-%d{yyyy-MM-dd}.log.gz">
          <PatternLayout pattern="%d %p %c{1.} [%t] %m%n" />
          <CronTriggeringPolicy schedule="0 0 0 * * ?"/>
          <DefaultRolloverStrategy>
            <Delete basePath="${baseDir}" maxDepth="2">
              <IfFileName glob="*/app-*.log.gz" />
              <IfLastModified age="60d" />
            </Delete>
          </DefaultRolloverStrategy>
        </RollingFile>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="RollingFile"/>
        </Root>
      </Loggers>
    </Configuration>

          示例二、它使用RollingFileAppender同时具有基于时间和大小的触发策略,将在同一天(1-100)创建最多100个存档,这些存档存储在基于当前年份和月份的目录中,并将使用gzip压缩每个存档并每小时滚动一次。在每次翻转期间,此配置将删除与“* / app - * .log.gz”匹配且30天或更早的文件,但保留最新的100 GB或最新的10个文件,以先到者为准。

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Properties>
        <Property name="baseDir">logs</Property>
      </Properties>
      <Appenders>
        <RollingFile name="RollingFile" fileName="${baseDir}/app.log"
              filePattern="${baseDir}/$${date:yyyy-MM}/app-%d{yyyy-MM-dd-HH}-%i.log.gz">
          <PatternLayout pattern="%d %p %c{1.} [%t] %m%n" />
          <Policies>
            <TimeBasedTriggeringPolicy />
            <SizeBasedTriggeringPolicy size="250 MB"/>
          </Policies>
          <DefaultRolloverStrategy max="100">
            <!--
            Nested conditions: the inner condition is only evaluated on files
            for which the outer conditions are true.
            -->
            <Delete basePath="${baseDir}" maxDepth="2">
              <IfFileName glob="*/app-*.log.gz">
                <IfLastModified age="30d">
                  <IfAny>
                    <IfAccumulatedFileSize exceeds="100 GB" />
                    <IfAccumulatedFileCount exceeds="10" />
                  </IfAny>
                </IfLastModified>
              </IfFileName>
            </Delete>
          </DefaultRolloverStrategy>
        </RollingFile>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="RollingFile"/>
        </Root>
      </Loggers>
    </Configuration>

        (3).Loggers节点,常见的有两种:Root和Logger.

           Root节点用来指定项目的根日志,如果没有单独指定Logger,那么就会默认使用该Root日志输出

             level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.

             AppenderRef:Root的子节点,用来指定该日志输出到哪个Appender.

           Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。

             level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.

             name:用来指定该Logger所适用的类或者类所在的包全路径,继承自Root节点.

             AppenderRef:Logger的子节点,用来指定该日志输出到哪个Appender,如果没有指定,就会默认继承自Root.如果指定了,那么会在指定的这个Appender和Root的Appender中都会输出,此时我们可以设置Logger的additivity="false"只在自定义的Appender中进行输出。

        (4).关于日志level.

          共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.

          All:最低等级的,用于打开所有日志记录.

          Trace:是追踪,就是程序推进以下,你就可以写个trace输出,所以trace应该会特别多,不过没关系,我们可以设置最低日志级别不让他输出.

          Debug:指出细粒度信息事件对调试应用程序是非常有帮助的.

          Info:消息在粗粒度级别上突出强调应用程序的运行过程.

          Warn:输出警告及warn以下级别的日志.

          Error:输出错误信息日志.

          Fatal:输出每个严重的错误事件将会导致应用程序的退出的日志.

          OFF:最高等级的,用于关闭所有日志记录.

          程序会打印高于或等于所设置级别的日志,设置的日志等级越高,打印出来的日志就越少

      4.比较完整的log4j2.xml配置模板

    <?xml version="1.0" encoding="UTF-8"?>
     <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
     <!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
     <!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
     <configuration status="WARN" monitorInterval="30">
         <!--先定义所有的appender-->
         <appenders>
         <!--这个输出控制台的配置-->
             <console name="Console" target="SYSTEM_OUT">
             <!--输出日志的格式-->
                 <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
             </console>
         <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用-->
         <File name="log" fileName="log/test.log" append="false">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
         </File>
         <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
             <RollingFile name="RollingFileInfo" fileName="${sys:user.home}/logs/info.log"
                          filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
                 <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->        
                 <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
                 <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
                 <Policies>
                     <TimeBasedTriggeringPolicy/>
                     <SizeBasedTriggeringPolicy size="100 MB"/>
                 </Policies>
             </RollingFile>
             <RollingFile name="RollingFileWarn" fileName="${sys:user.home}/logs/warn.log"
                          filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log">
                 <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
                 <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
                 <Policies>
                     <TimeBasedTriggeringPolicy/>
                     <SizeBasedTriggeringPolicy size="100 MB"/>
                 </Policies>
             <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
                 <DefaultRolloverStrategy max="20"/>
             </RollingFile>
             <RollingFile name="RollingFileError" fileName="${sys:user.home}/logs/error.log"
                          filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log">
                 <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
                 <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
                 <Policies>
                     <TimeBasedTriggeringPolicy/>
                     <SizeBasedTriggeringPolicy size="100 MB"/>
                 </Policies>
             </RollingFile>
         </appenders>
         <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
         <loggers>
             <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
             <logger name="org.springframework" level="INFO"></logger>
             <logger name="org.mybatis" level="INFO"></logger>
             <root level="all">
                 <appender-ref ref="Console"/>
                 <appender-ref ref="RollingFileInfo"/>
                 <appender-ref ref="RollingFileWarn"/>
                 <appender-ref ref="RollingFileError"/>
             </root>
         </loggers>
     </configuration>

    三、slf4j+log4j2

    3.1、POM依赖

            <!-- 日志 门面 -->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.25</version>
            </dependency>
            <!-- 桥接器-->
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-slf4j-impl</artifactId>
                <version>2.11.1</version>
            </dependency>
            <!-- log4j2 -->
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-core</artifactId>
                <version>2.11.1</version>
            </dependency>
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-api</artifactId>
                <version>2.11.1</version>
            </dependency>

    3.2、配置文件

      使用上述log4j2.xml 配置文件即可

    3.3、程序代码

      需修改,使用slf4j统一的日志门面工厂

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class ApplicationMain {
        private static Logger logger = LoggerFactory.getLogger(ApplicationMain.class);
    
        public static void main(String[] args) {
            // 记录debug级别的信息
            logger.debug("This is debug message.");
            // 记录info级别的信息
            logger.info("This is info message.");
            // 记录error级别的信息
            logger.error("This is error message.");
        }
    }

       

  • 相关阅读:
    线段树小结
    线段树 区间合并
    线段树
    线段树离散化+区间修改
    线段树模板

    geatpy
    基于Anaconda 安装 geatpy 和 tensorflow
    Python 求“元组、列表、字典、数组和矩阵”的大小
    np.array()和np.mat()区别
  • 原文地址:https://www.cnblogs.com/bjlhx/p/11060921.html
Copyright © 2020-2023  润新知