如何在app start上禁用创建空日志文件?

bin*_*all 16 c# log4net winforms log4net-configuration

我已成功在我的应用程序中配置了log4net,但有一件事对我来说有点烦人.

即使没有错误发生,我的应用程序启动后也会创建(空)日志文件.我想在出现一些错误后才创建日志文件.

Loa*_*ian 14

我实际上在这个帖子中找到了一种方法:

http://www.l4ndash.com/Log4NetMailArchive/tabid/70/forumid/1/postid/18271/view/topic/Default.aspx

我测试了第一种方法,它的工作原理.为了防止链接不再好,我将在这里重现代码.基本上,作者声明有两种方法可以做到这一点.

第一种方式:

如果该记录器的适当阈值有效,则创建仅获取锁定(并创建文件)的新锁定模型.

public class MyLock : log4net.Appender.FileAppender.MinimalLock
{
      public override Stream AcquireLock()
      {
            if (CurrentAppender.Threshold == log4net.Core.Level.Off)
                  return null;

            return base.AcquireLock();
      }
}
Run Code Online (Sandbox Code Playgroud)

现在在配置文件中,将阈值设置为以:

<threshold value="OFF" />
Run Code Online (Sandbox Code Playgroud)

并确保在建模时设置这个新的LockingModel:

<lockingModel type="Namespace.MyLock" />
Run Code Online (Sandbox Code Playgroud)

我正在使用滚动文件appender.

第二种方法列在链接中.我没有尝试过这种技术,但它似乎在技术上是合理的.

  • 对于任何想要回答答案的人,我相信Jon Skeet的回答实际上是对这个答案的评论. (2认同)

Rem*_*sen 7

我知道这是一个老问题,但我认为这对其他人有用.

我们遇到了类似的情况,即如果没有发生错误,应用程序不应该留下空的日志文件.

我们通过创建以下自定义LockingModel类来解决它:

public class MinimalLockDeleteEmpty : FileAppender.MinimalLock
{
    public override void ReleaseLock()
    {
        base.ReleaseLock();

        var logFile = new FileInfo(CurrentAppender.File);
        if (logFile.Exists && logFile.Length <= 0)
        {
            logFile.Delete();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它派生自FileAppender.MinimalLock类,它将在写入每条日志消息后释放对日志文件的锁定.

我们添加了额外的功能,如果日志文件在锁定释放后仍为空,则会删除日志文件.如果应用程序运行并退出而没有任何错误,它可以防止应用程序留下空的错误日志文件.

优点

  • 它仍将在Log4Net的配置阶段创建一个空的日志文件,确保在应用程序的其余部分启动之前记录正在运行.但是,会立即删除日志文件.
  • 它不需要您通过将阈值设置为"OFF"来关闭配置文件中的日志记录,并且稍后在编写第一个日志事件之前以编程方式打开日志记录.

缺点

  • 这很可能是管理日志文件的一种缓慢方法,因为在写入日志文件的每个日志事件之后,将调用ReleaseLock方法和文件长度检查.只有当您希望错误很少时才使用它,并且在没有错误时,日志文件不应该存在是业务要求.
  • 空白时创建和删除日志文件.如果您有其他工具监视日志目录以查找文件系统更改,则可能会出现问题.但是,这在我们的情况下不是问题.


小智 6

以下对我有用。配置记录器时,第一次调用OpenFile()。后续调用是在生成实际日志消息时。

class CustomFileAppender : RollingFileAppender
{
    private bool isFirstTime = true;
    protected override void OpenFile(string fileName, bool append)
    {
        if (isFirstTime)
        {
            isFirstTime = false;
            return;
        }

        base.OpenFile(fileName, append);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在配置文件中,更改附加程序

<log4net>
<appender name="RollingFile" type="<your namespace>.CustomFileAppender">
...
</log4net>
Run Code Online (Sandbox Code Playgroud)

来自log4Net源的顺序如下:


  • 对OpenFile()的首次调用是由于从FileAppender的构造函数调用了ActivateOptions()。
  • 生成日志消息时,AppenderSkeleton的DoAppend()调用PreAppendCheck()
  • PreAppendCheck()在TextWriterAppender(FileAppender的基础)中被覆盖。
  • 如果文件尚未打开,则重写的PreAppendCheck()会调用虚拟PrepareWriter
  • FileAppender的PrepareWriter()调用SafeOpenFile(),而SafeOpenFile()依次调用OpenFile()