【问题标题】:Setting a log file name to include current date in Log4j设置日志文件名以在 Log4j 中包含当前日期
【发布时间】:2010-09-16 14:05:33
【问题描述】:

我想将 log4j 和 log4net appender 的日志文件名设置为当前日期。我们正在进行每日翻转,但当前日志文件没有日期。日志文件名格式为

logname.2008-10-10.log

有人知道我这样做的最佳方法吗?

edit:我忘了提到我们也想在 log4net 中这样做。此外,任何解决方案都需要在 JBoss 中可用。

【问题讨论】:

    标签: java .net logging log4net log4j


    【解决方案1】:

    DailyRollingFileAppender 正是您要搜索的内容。

    <appender name="roll" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="application.log" />
        <param name="DatePattern" value=".yyyy-MM-dd" />
        <layout class="org.apache.log4j.PatternLayout"> 
          <param name="ConversionPattern" 
              value="%d{yyyy-MMM-dd HH:mm:ss,SSS} [%t] %c %x%n  %-5p %m%n"/>
        </layout>
      </appender>
    

    【讨论】:

    • 这不是简单地创建一个名为“application.log”的日志文件,并且只将日期模式放在滚动的日志文件中吗?
    • 因此,您每天都会获得一个单独的日志文件。但是今天的日志文件将被命名为 application.log,没有日期。在大多数情况下都可以。
    • “DatePattern”上的两个 cmets: - 我使用“.yyyy-MM-dd.lo\g”为所有日志文件获取相同的扩展名。 - 需要 g 之前的反斜杠(至少对于 log4net)以防止 .Net 应用预定义的“g”格式。
    • @gyrolf,应用您提到的格式,您的日志最终是否为 mylog.log.yyyy-MM-dd.log?还是您以某种方式删除了以前的扩展名?
    • 来自 log4j 文档:已观察到 DailyRollingFileAppender 出现同步问题和数据丢失。(logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/…)。你真的应该关注@shinds 的回答
    【解决方案2】:

    使用 log4j.properties 文件,并在我的 POM 中包含 apache-log4j-extras 1.1 和 log4j 1.2.16

    log4j.appender.LOGFILE=org.apache.log4j.rolling.RollingFileAppender
    log4j.appender.LOGFILE.RollingPolicy=org.apache.log4j.rolling.TimeBasedRollingPolicy
    log4j.appender.LOGFILE.RollingPolicy.FileNamePattern=/logs/application_%d{yyyy-MM-dd}.log
    

    【讨论】:

    • ^---^ 专业级:99 log4j.appender.out.RollingPolicy.FileNamePattern=logs/%d{yyyy-MM-dd HH-mm-ss} cron-script-x/out.log log4j.appender.err.RollingPolicy.FileNamePattern=logs/%d{yyyy-MM-dd HH-mm-ss} cron-script-x/err.log
    • 截至目前,下载镜像链接全部失效。您仍然可以在存档存储库中找到该库:archive.apache.org/dist/logging/log4j/companions/extras
    • log4j.appender..DatePattern=yyyy-MM-dd 可以解决问题。文件名每天滚动,无需额外依赖
    【解决方案3】:

    我 99% 确定 RollingFileAppender/DailyRollingFileAppender 虽然为您提供所需的日期滚动功能,但无法指定当前日志文件也应使用 DatePattern

    您也许可以简单地继承 RollingFileAppender(或 DailyRollingFileAppender,我忘记了 log4net 中的哪个)并修改命名逻辑。

    【讨论】:

      【解决方案4】:

      我已经创建了一个可以做到这一点的附加程序。 http://stauffer.james.googlepages.com/DateFormatFileAppender.java

      /*
       * Copyright (C) The Apache Software Foundation. All rights reserved.
       *
       * This software is published under the terms of the Apache Software
       * License version 1.1, a copy of which has been included with this
       * distribution in the LICENSE.txt file.  */
      
      package sps.log.log4j;
      
      import java.io.IOException;
      import java.io.File;
      import java.text.SimpleDateFormat;
      import java.util.Date;
      
      import org.apache.log4j.*;
      import org.apache.log4j.helpers.LogLog;
      import org.apache.log4j.spi.LoggingEvent;
      
      /**
       * DateFormatFileAppender is a log4j Appender and extends 
       * {@link FileAppender} so each log is 
       * named based on a date format defined in the File property.
       *
       * Sample File: 'logs/'yyyy/MM-MMM/dd-EEE/HH-mm-ss-S'.log'
       * Makes a file like: logs/2004/04-Apr/13-Tue/09-45-15-937.log
       * @author James Stauffer
       */
      public class DateFormatFileAppender extends FileAppender {
      
        /**
         * The default constructor does nothing.
         */
        public DateFormatFileAppender() {
        }
      
        /**
         * Instantiate a <code>DailyRollingFileAppender</code> and open the
         * file designated by <code>filename</code>. The opened filename will
         * become the ouput destination for this appender.
         */
        public DateFormatFileAppender (Layout layout, String filename) throws IOException {
          super(layout, filename, true);
        }
      
        private String fileBackup;//Saves the file pattern
        private boolean separate = false;
      
        public void setFile(String file) {
          super.setFile(file);
          this.fileBackup = getFile();
        }
      
        /**
         * If true each LoggingEvent causes that file to close and open.
         * This is useful when the file is a pattern that would often
         * produce a different filename.
         */
        public void setSeparate(boolean separate) {
          this.separate = separate;
        }
      
        protected void subAppend(LoggingEvent event) {
          if(separate) {
              try {//First reset the file so each new log gets a new file.
                  setFile(getFile(), getAppend(), getBufferedIO(), getBufferSize());
              } catch(IOException e) {
                  LogLog.error("Unable to reset fileName.");
              }
          }
          super.subAppend(event);
        }
      
      
        public
        synchronized
        void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize)
                                                                  throws IOException {
          SimpleDateFormat sdf = new SimpleDateFormat(fileBackup);
          String actualFileName = sdf.format(new Date());
          makeDirs(actualFileName);
          super.setFile(actualFileName, append, bufferedIO, bufferSize);
        }
      
        /**
         * Ensures that all of the directories for the given path exist.
         * Anything after the last / or \ is assumed to be a filename.
         */
        private void makeDirs (String path) {
          int indexSlash = path.lastIndexOf("/");
          int indexBackSlash = path.lastIndexOf("\\");
          int index = Math.max(indexSlash, indexBackSlash);
          if(index > 0) {
              String dirs = path.substring(0, index);
      //        LogLog.debug("Making " + dirs);
              File dir = new File(dirs);
              if(!dir.exists()) {
                  boolean success = dir.mkdirs();
                  if(!success) {
                      LogLog.error("Unable to create directories for " + dirs);
                  }
              }
          }
        }
      
      }
      

      【讨论】:

        【解决方案5】:

        我不知道在 Java 中是否可行,但在 .NET 中,RollingFileAppender 上的 StaticLogFileName 属性可以满足您的需求。默认为真。

        <staticLogFileName value="false"/>
        

        完整配置:

        <appender name="DefaultFileAppender" type="log4net.Appender.RollingFileAppender">
          <file value="application"/>
          <staticLogFileName value="false"/>
          <appendToFile value="true" />
          <rollingStyle value="Date" />
          <datePattern value="yyyy-MM-dd&quot;.log&quot;" />
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
          </layout>
        </appender>
        

        &amp;quot;.log&amp;quot; 用于不让日期格式识别日志中的全局日期模式'g'。

        【讨论】:

        • 这正是我想要的。
        • 只是为了澄清:yyyy-MM-dd&amp;quot;.log&amp;quot; 中的 HTML 实体 &amp;quot 是否应该存在,而不是 '
        【解决方案6】:

        此示例将为每分钟创建记录器,如果您想更改每一天,请更改 DatePattern 值。

        <appender name="ASYNC" class="org.apache.log4j.DailyRollingFileAppender">
           <param name="File" value="./applogs/logger.log" />
           <param name="Append" value="true" />
           <param name="Threshold" value="debug" />
           <appendToFile value="true" />
           <param name="DatePattern" value="'.'yyyy_MM_dd_HH_mm"/>
           <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
              <param name="fileNamePattern" value="./applogs/logger_%d{ddMMMyyyy HH:mm:ss}.log"/>
              <param name="rollOver" value="TRUE"/>
           </rollingPolicy>
           <layout class="org.apache.log4j.PatternLayout">
              <param name="ConversionPattern" value="%d{ddMMMyyyy HH:mm:ss,SSS}^[%X{l4j_mdc_key}]^[%c{1}]^ %-5p %m%n" />
           </layout>
        </appender>
        <root>
           <level value="info" />
           <appender-ref ref="ASYNC" />
        </root>
        

        【讨论】:

          【解决方案7】:

          作为对提到 DailyRollingFileAppender 的两个答案的回应(抱歉,我没有足够的代表直接评论它们,我认为这需要提及),我会警告说,不幸的是该类的开发人员有记录它表现出同步和数据丢失,并建议应为新部署寻求替代方案。

          DailyRollingFileAppender JavaDoc

          【讨论】:

            【解决方案8】:

            您可以动态设置FileAppender

            SimpleLayout layout = new SimpleLayout();           
            FileAppender appender = new FileAppender(layout,"logname."+new Date().toLocaleString(),false);
            logger.addAppender(appender); 
            

            【讨论】:

            • 请注意文件名中的斜杠“/”。我宁愿用户:"logname"+new Date().format("yyyy-mm-dd-hh-MM")+".log"
            • 这将仅在应用启动时创建新的日志文件,并且不会按日期将您的日志剪切为文件
            【解决方案9】:

            即使你像@gedevan 建议的那样使用 DailyRollingFileAppender,你仍然会得到logname.log.2008-10-10(一天后,因为前一天的日志将被存档,并且日期将连接到它的文件名)。 所以如果你想在最后使用 .log,你必须在 DatePattern 上这样做:

            log4j.appender.file.DatePattern='.'yyyy-MM-dd-HH-mm'.log'

            【讨论】:

              【解决方案10】:

              您可以像这样以编程方式进行:

                      String dateFile = LocalDate.now().toString() + ".log";
                      Enumeration enm = Logger.getRootLogger().getAllAppenders();
                      Appender appender = null;
                      while(enm.hasMoreElements()){
                          appender = (Appender)enm.nextElement();
                          String c = appender.getClass().toString();
                          if(c.contains("FileAppender")){
                              String f = ((FileAppender)appender).getFile();
                              ((FileAppender)appender).setFile(f+dateFile);
                              System.out.println("From:"+f+" to:"+dateFile);
                          }
                      }
              

              【讨论】:

                猜你喜欢
                • 2014-07-04
                • 2012-02-06
                • 1970-01-01
                • 2014-11-17
                • 2019-04-11
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2010-09-10
                相关资源
                最近更新 更多