在log4j2中,如何将RollingFile附加程序的namedEmptyFiles配置为false? [英] In log4j2, how to configure renameEmptyFiles to be false for the RollingFile appender?

查看:162
本文介绍了在log4j2中,如何将RollingFile附加程序的namedEmptyFiles配置为false?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用log4j 2和RollingFile附加器:

I'm using log4j 2 and RollingFile appender:

<RollingFile name="mylog"
fileName="mylog.log"
filePattern="mylog.log.%d{yyyy-MM-dd}.log">
  <PatternLayout>
    <pattern>[%d] [%-5p] [%-8t] %F:%L %m%n</pattern>
  </PatternLayout>
  <Policies>
    <TimeBasedTriggeringPolicy interval="1"/>
  </Policies>
</RollingFile>

日志文件每天都会重命名.但是 FileRenameAction的Javadoc表示有一个选项renameEmptyFiles,默认情况下为false,因此,如果某天的日志为空,则将其删除,而不是重命名,将日期附加到文件名上.自从我想拥有日志文件(即使它为空)后,如何将其配置为true?

The log files do get renamed daily. But the Javadoc of FileRenameAction class indicates there is an option renameEmptyFiles which is false by default so if a day's log is empty it deletes it instead of rename it appending the date to the file name. How to configure it to true since I'd like to have the log file even if it's empty?

推荐答案

我制作了一个提供所需功能的小插件.我只是扩展了DefaultRolloverStrategy并替换了(因为它的所有字段都是final)从rollover()返回的RolloverDescription对象.我从DefaultRolloverStrategy复制了静态@PluginFactory代码,这是Log4j 2插件系统所需的.

I made a little plugin that offers the desired functionality. I simply extended the DefaultRolloverStrategy and replaced (as all of its fields are final) the RolloverDescription object that is returned from rollover(). I copied the static @PluginFactory code from DefaultRolloverStrategy as it's required for the Log4j 2 plugin system.

这是代码:

import java.util.zip.Deflater;

import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy;
import org.apache.logging.log4j.core.appender.rolling.RollingFileManager;
import org.apache.logging.log4j.core.appender.rolling.RolloverDescription;
import org.apache.logging.log4j.core.appender.rolling.RolloverDescriptionImpl;
import org.apache.logging.log4j.core.appender.rolling.action.Action;
import org.apache.logging.log4j.core.appender.rolling.action.FileRenameAction;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.lookup.StrSubstitutor;
import org.apache.logging.log4j.core.util.Integers;

@Plugin( name = "KeepEmptyFilesRolloverStrategy", category = "Core", printObject = true )
public class KeepEmptyFilesRolloverStrategy extends DefaultRolloverStrategy
{
   private static final int MIN_WINDOW_SIZE = 1;
   private static final int DEFAULT_WINDOW_SIZE = 7;

   @PluginFactory
   public static KeepEmptyFilesRolloverStrategy createStrategy( @PluginAttribute( "max" ) final String max,
                                                                @PluginAttribute( "min" ) final String min,
                                                                @PluginAttribute( "fileIndex" ) final String fileIndex,
                                                                @PluginAttribute( "compressionLevel" ) final String compressionLevelStr,
                                                                @PluginElement( "Actions" ) final Action[] customActions,
                                                                @PluginAttribute( value = "stopCustomActionsOnError", defaultBoolean = true ) final boolean stopCustomActionsOnError,
                                                                @PluginConfiguration final Configuration config )
   {
      final boolean useMax = fileIndex == null ? true : fileIndex.equalsIgnoreCase( "max" );
      int minIndex = MIN_WINDOW_SIZE;
      if ( min != null )
      {
         minIndex = Integer.parseInt( min );
         if ( minIndex < 1 )
         {
            LOGGER.error( "Minimum window size too small. Limited to " + MIN_WINDOW_SIZE );
            minIndex = MIN_WINDOW_SIZE;
         }
      }
      int maxIndex = DEFAULT_WINDOW_SIZE;
      if ( max != null )
      {
         maxIndex = Integer.parseInt( max );
         if ( maxIndex < minIndex )
         {
            maxIndex = minIndex < DEFAULT_WINDOW_SIZE ? DEFAULT_WINDOW_SIZE : minIndex;
            LOGGER.error( "Maximum window size must be greater than the minimum windows size. Set to "
                          + maxIndex );
         }
      }
      final int compressionLevel = Integers.parseInt( compressionLevelStr, Deflater.DEFAULT_COMPRESSION );
      return new KeepEmptyFilesRolloverStrategy( minIndex,
                                                 maxIndex,
                                                 useMax,
                                                 compressionLevel,
                                                 config.getStrSubstitutor(),
                                                 customActions,
                                                 stopCustomActionsOnError );
   }

   protected KeepEmptyFilesRolloverStrategy( int minIndex,
                                             int maxIndex,
                                             boolean useMax,
                                             int compressionLevel,
                                             StrSubstitutor subst,
                                             Action[] customActions,
                                             boolean stopCustomActionsOnError )
   {
      super( minIndex, maxIndex, useMax, compressionLevel, subst, customActions, stopCustomActionsOnError );
   }

   @Override
   public RolloverDescription rollover( final RollingFileManager manager ) throws SecurityException
   {
      RolloverDescription oldResult = super.rollover( manager );

      // Fail fast (ClassCastException) if implementation of DefaultRolloverStrategy 
      // ever changes and uses a different Action type. 
      FileRenameAction oldRenameAction = (FileRenameAction) oldResult.getSynchronous();
      FileRenameAction newRenameAction = new FileRenameAction( oldRenameAction.getSource(),
                                                               oldRenameAction.getDestination(),
                                                               true );

      RolloverDescription newResult = new RolloverDescriptionImpl( oldResult.getActiveFileName(),
                                                                   oldResult.getAppend(),
                                                                   newRenameAction,
                                                                   oldResult.getAsynchronous() );

      return newResult;
   }
}

要使用此类,只需在Log4j 2 XML配置中引用它,例如像这样:

To use this class, simply reference it in the Log4j 2 XML configuration, e.g. like this:

<RollingFile name="RollingFile" fileName="/usr/local/glassfish4.1-webprofile/glassfish/domains/domain1/logs/server.log" filePattern="/usr/local/glassfish4.1-webprofile/glassfish/domains/domain1/logs/server.%d{yyyyMMdd-HH:mm}.log">
  <KeepEmptyFilesRolloverStrategy/>
  <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
  <CronTriggeringPolicy schedule="0 * * * * ?"/>
</RollingFile>

该实现的灵感来自

The implementation was inspired by this related answer.

在旁注中,可能需要使用新的CronTriggeringPolicy来完全创建空的日志文件,因为它使用了单独的线程.从SO的其他答案来看,只要Appender不写任何内容,至少其他一些策略就无法对触发器做出反应.

On a sidenote, it might be necessary to use the new CronTriggeringPolicy to have empty log files being created at all, as it uses a separate thread. Judging from some other answers on SO, at least some of the other policies cannot react to the trigger as long as the Appender doesn't write out anything.

这篇关于在log4j2中,如何将RollingFile附加程序的namedEmptyFiles配置为false?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆