我如何设置 log4net 每天将我的文件记录到不同的文件夹中?

Posted

技术标签:

【中文标题】我如何设置 log4net 每天将我的文件记录到不同的文件夹中?【英文标题】:How I can set log4net to log my files into different folders each day? 【发布时间】:2011-01-24 01:08:40 【问题描述】:
    我想将每天的所有日志保存在名为 YYYYMMdd 的文件夹中 - log4net 应根据系统日期时间处理创建新文件夹 - 我该如何设置? 我想将白天的所有日志保存到 n 个 1MB 的文件中 - 我不想重写旧文件,而是想在一天内真正拥有所有日志 - 我该如何设置?

我用的是 C#

问候 亚历克斯

【问题讨论】:

【参考方案1】:

试试这个(应该没问题!):

<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
  <file value="logs\\" />
  <appendToFile value="true" />
  <DatePattern value="yyyy\\\\MM\\\\dd'.inf.log'" />
  <rollingStyle value="Date" />
  <param name="StaticLogFileName" value="false" />
  <layout type="log4net.Layout.PatternLayout">
    <header value="[Header]&#13;&#10;" />
    <footer value="[Footer]&#13;&#10;" />
    <conversionPattern value="%date [%thread] %-5level %logger [%ndc] &lt;%propertyauth&gt; - %message%newline" />
  </layout>
</appender>

它将创建一个名为 'logs\2010\04\02.inf.log' 的日志文件(假设日期为 2010-04-02)

【讨论】:

单引号表示什么? '.inf.log' 完美运行,只是一个注释,只有双反斜杠就足够了。 &lt;file value="logs\" /&gt;&lt;DatePattern value="yyyy\\MM\\dd'.inf.log'" /&gt; 应该可以正常工作。 我认为你需要使用&lt;file value="logs\\" /&gt;&lt;DatePattern value="yyyy\\\\MM\\\\dd'.inf.log'" /&gt;来转义```否则它会转义第一个'M'和第一个'd'【参考方案2】:

谢谢大家。 我们创建了 SortByFolderFileAppender,它继承自 RollingFileAppender

最终结果示例: 某处\Logs\20100305\Client-104615.0

namespace CustomLogging

  public class SortByFolderFileAppender : log4net.Appender.RollingFileAppender
  
    protected override void OpenFile(string fileName, bool append)
    
      //Inject folder [yyyyMMdd] before the file name
      string baseDirectory = Path.GetDirectoryName(fileName);
      string fileNameOnly = Path.GetFileName(fileName);
      string newDirectory = Path.Combine(baseDirectory, DateTime.Now.ToString("yyyyMMdd"));
      string newFileName = Path.Combine(newDirectory, fileNameOnly);

      base.OpenFile(newFileName, append);
    
  

<appender name="SortByFolderFileAppender" type="CustomLogging.SortByFolderFileAppender">
  <file type="log4net.Util.PatternString" value="Logs\Client"/>
  <appendToFile value="true"/>
  <rollingStyle value="Composite"/>
  <datePattern value="-HHmmss"/>
  <maxSizeRollBackups value="40"/>
  <maximumFileSize value="1MB"/>
  <countDirection value="1"/>
  <encoding value="utf-8"/>
  <staticLogFileName value="false"/>
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%dateHH:mm:ss.fff|%-5level|%message%newline"/>
  </layout>
</appender>

【讨论】:

OpenFile 中是否可以实际附加到当前日志?我想以这种方式向我的自定义附加程序添加几条消息。 我设法使用 LogLog.Warn/LogLog.Error 将某些内容写入 stderr,但 log4net 方法可能无法访问当前日志? 如果 staticLogFileName 设置为 True,此解决方案将无法按预期工作。就我而言,我希望每天都有不同的文件夹,但里面的文件名相同。如果此属性设置为 true,log4net 会将文件复制到为 appender 的 File 属性指定的文件夹中,并且注入的文件夹保持为空! 我查看了log4net源代码,似乎没有可能绕过我上面写的。仅将 static 设置为 true,然后处理文件并从其名称中删除日期模式。 另外,如果您更改记录器代码中的某些选项,并在 appender 上调用 ActivateOptions,此解决方案将在路径中添加新文件夹名称,例如:logs\23-03-2014\23- 03-2014\23-03-2014... 以此类推,每次通话。小心点!【参考方案3】:

我相信,您可以基于 FileAppender 类创建自己的附加程序。您可能需要覆盖 OpenFile 方法才能在正确的位置创建文件。

【讨论】:

【参考方案4】:

您可以使用 rollinglogfileappender 创建按日期命名的文件并在午夜启动一个新文件。然后只需编写一个脚本,将它们移动到 00.01 的正确地图。

关于在一天内记录所有文件,每个文件最多 1 MB,这是一个示例:

<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
  <file type="log4net.Util.PatternString" value="Logging\\MWLog"/>
  <appendToFile value="true"/>
  <rollingStyle value="Composite"/>
  <datePattern value="-yyyyMMdd"/>
  <maxSizeRollBackups value="-1"/>
  <maximumFileSize value="1MB"/>
  <countDirection value="1"/>
  <encoding value="utf-8"/>
  <staticLogFileName value="false"/>
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%dateHH:mm:ss.fff|%-5level|%message%newline"/>
  </layout>
</appender>

【讨论】:

【参考方案5】:

使用 SortByFolderFileAppender 从上面的答案构建。

这就是我们使用日志文件名的滚动日期解决问题的方法。我将 staticLogFileName 更改为 true,以便将整个文件名传递给 OpenFile 方法。

如果文件名以“.log”结尾,则无需附加任何内容。我猜发生了某种锁定,我希望 log4net 再次尝试使用相同的文件名,希望之前的锁定已被释放。

虽然,我不确定如果文件被锁定并且不会放开它,这是否最终会导致对 OpenFile 的无限调用。我们确实使用生产者消费者模式创建了一个 Web 服务,以将系统中所有应用程序的所有内容记录在一个位置,该系统目前有 10 个并且还在增长。

我们不需要将 log4net 包含到任何其他应用程序中,但我们需要创建一个可供所有应用程序访问的 Web 客户端类,以用于登录到 Web 服务。

文件名的结果是“Logs\Client\2017\11\08.log”,显然每天都在变化。

protected override void OpenFile( string fileName, bool append )

    // append "\yyyy\mm\dd.log" to create the correct filename.
    if ( !fileName.EndsWith( ".log") )
        fileName = $@"fileName\DateTime.Now:yyyy\\MM\\dd.log";

    base.OpenFile( fileName, append );

从上面修改配置。

<appender name="xxxRollingFileAppender" type="namespace.xxxRollingFileAppender">
    <file value="Logs\Client"/>
    <staticLogFileName value="true"/>
    <appendToFile value="true"/>
    <maxSizeRollBackups value="40"/>
    <maximumFileSize value="1MB"/>
    <encoding value="utf-8"/>
    <layout type="log4net.Layout.PatternLayout">
       <conversionPattern value="%dateHH:mm:ss.fff|%-5level|%message%newline"/>
    </layout>
</appender>

【讨论】:

以上是关于我如何设置 log4net 每天将我的文件记录到不同的文件夹中?的主要内容,如果未能解决你的问题,请参考以下文章

您可以在代码中配置 log4net 而不是使用配置文件吗?

如何使用 log4net 每个任务登录到不同的文件?

如何使用 Log4net 进行日志记录?

批处理脚本 - 每天将视频传输到下一个文件夹

Log4net 在记录几秒钟后将日志路径更改为安装文件夹。这是为啥?

SQLite - 每天将 .csv 数据导入数据库