删除过期文件有个坑,好多博文都说删除过期日志文件的配置通过max=数字控制.这是不对的这个只是控制某时间段内(根据配置不同)文件的数目.它并不会关心你的目录下一共有多少个日志文件了. 可想而知, 这样随着时间的推移, 虽然每个时间区间内日志数目控制在范围内, 但是, 总日志文件个数, 依然日益膨胀.

正确的应该如下:

<?xml version="1.0" encoding="UTF-8"?>

<Configuration status="WARN" monitorInterval="300">   <!-- debug="true" xmlns:log4j="http://jakarta.apache.org/log4j/"-->
    <properties>
        <property name="LOG_HOME">logs/kg</property>
        <property name="FILE_NAME">kg</property>
    </properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %class{36}:%M(%L)] - %msg%xEx%n"/>
        </Console>
        <RollingRandomAccessFile name="MyFile"
                                 fileName="${LOG_HOME}/${FILE_NAME}.log"
                                 filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd-HH}-%i.log">
            <PatternLayout
                    pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %class{36}:%M(%L)] - %msg%xEx%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1"/>      <!--每1小时/分/... 生成一个文件, 时间依据filePattern的配置-->
                <SizeBasedTriggeringPolicy size="5 MB"/>
            </Policies>
            <DefaultRolloverStrategy max="30">
                <Delete basePath="${LOG_HOME}/$${date:yyyy-MM}/" maxDepth="2">
                    <IfFileName glob="*.log" />
                    <!--!Note: 这里的age必须和filePattern协调, 后者是精确到HH, 这里就要写成xH, xd就不起作用
                    另外, 数字最好>2, 否则可能造成删除的时候, 最近的文件还处于被占用状态,导致删除不成功!-->
                    <!--7天-->
                    <IfLastModified age="168H" />
                </Delete>
            </DefaultRolloverStrategy>
        </RollingRandomAccessFile>
    </Appenders>

    <Loggers>
        <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
        <logger name="org.springframework" level="INFO"/>
        <logger name="org.mybatis" level="INFO"/>
        <Logger name="mylog" level="debug" additivity="false">
            <AppenderRef ref="MyFile"/>
            <AppenderRef ref="Console"/>
        </Logger>
        <Root level="debug">
            <AppenderRef ref="MyFile"/>
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>

</Configuration>

注意:

  • filePattern定义的日志文件后缀精确的时间决定了定期生成日志文件. 精确到dd, 即%d{yyyy-MM-dd}, 则会每天生成一个文件, 精确到HH, 则会每时生成一个文件, ...
  • Delete标签内决定了删除过期文件的规则. 需要注意这里的IfLastModified .age要和filePattern精确的时间一致, 否则貌似无效.
    我这里日志文件会按日期放入子文件夹内, 所以要想统计总数, 需要递归统计, 故设置maxDepth=2.

然后贴一个比较常用的配置:

<?xml version="1.0" encoding="UTF-8" ?>
<Configuration status="warn" monitorInterval="30" strict="true"
               schema="Log4J-V2.2.xsd">
    <Properties>
        <Property name="log_level">info</Property>
    </Properties>
    <Appenders>
        <!-- 输出到控制台 -->
        <Console name="Console" target="SYSTEM_OUT">
            <ThresholdFilter level="${log_level}" onMatch="ACCEPT" onMismatch="DENY" />
            <PatternLayout pattern="%d{yyyy-MM-dd'T'HH:mm:ss.SSS} [%t] %p - %c - %m%n" />
        </Console>
        <!-- 与properties文件中位置存在冲突,如有问题,请注意调整 -->
        <RollingFile name="logFile" fileName="logs/app/test.log"
                     filePattern="logs/app/history/test-%d{MM-dd-yyyy}-%i.log.gz">
            <ThresholdFilter level="${log_level}" onMatch="ACCEPT" onMismatch="DENY"  />
            <PatternLayout pattern="%d{yyyy-MM-dd'T'HH:mm:ss.SSS} [%p] [%c:%L] -- %m%n" />
            <Policies>
                <!-- 按天递计算频率 -->
                <TimeBasedTriggeringPolicy interval="1" />
                <SizeBasedTriggeringPolicy size="500 MB" />
                <OnStartupTriggeringPolicy />
            </Policies>
            <!-- 删除策略配置 -->
            <DefaultRolloverStrategy max="5">
                <Delete basePath="logs/app/history" maxDepth="1">
                    <IfFileName glob="*.log.gz"/>
                    <IfLastModified age="7d"/>
                </Delete>
                <Delete basePath="logs/app/history" maxDepth="1">
                    <IfFileName glob="*.docx"/>
                </Delete>
                <Delete basePath="logs/app/history" maxDepth="1">
                    <IfFileName glob="*.vsdx"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
        <Async name="Async" bufferSize="2000" blocking="false">
            <AppenderRef ref="logFile"/>
        </Async>
    </Appenders>

    <Loggers>
        <Root level="${log_level}">
            <AppenderRef ref="Console" />
            <AppenderRef ref="Async" />
        </Root>
        <!-- 配置个例 -->
        <Logger name="com.xx.filter" level="info" />
    </Loggers>
</Configuration>

 这里面介绍的比较详细,比如一些删除策略的修改: RollingFileAppender 使用基于时间和文件大小的触发规则,每天最多生成 100 个归档日志文件,使用 gzip 压缩,存放在当前年月目录,每小时都会滚动。每次滚动都会删除匹配 */app-*.log.gz 、达到或超过 30 天的文件,但会保留最近 100 GB 的文件或最近的 1000 个文件(这两个条件哪个先满足就使用哪一个条件)。

<?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="1000" />
              </IfAny>
            </IfLastModified>
          </IfFileName>
        </Delete>
      </DefaultRolloverStrategy>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="RollingFile"/>
    </Root>
  </Loggers>
</Configuration>