如何以编程方式强制log4net释放日志文件以便可以对其进行访问?

时间:2019-05-22 16:52:33

标签: c# log4net

我需要在执行大型过程后以日志文件作为附件发送电子邮件,以便用户可以识别任何问题。我们使用log4net来处理所有日志记录,但我无法使log4net释放文件,因此无法将其作为附件添加。

到目前为止,我遵循以下问题的结果:How to stop log4net from logging and release the last file关于将附加器阈值设置为“关闭”,但是由于DLL没有释放日志文件,我仍然收到异常消息。我可以在调试器中验证该附加程序实际上处于“关闭”状态,但是进程资源管理器确认我的exe仍在文件中保持锁定。

这是我从链接的问题中得到的方法:

 private static void SetThreshold(string appenderName, log4net.Core.Level threshold)
        {
            foreach (log4net.Appender.AppenderSkeleton appender in log4net.LogManager.GetRepository().GetAppenders())
            {
                if (appender.Name == appenderName)
                {
                    appender.Threshold = threshold;
                    break;
                }
            }
        }

任何有关强制释放此日志的想法都将非常有帮助。谢谢

3 个答案:

答案 0 :(得分:0)

日志已打开以供写入,因此释放锁的唯一方法是停止应用程序。您确实有以下选择:1)使用maximumFileSize设置将日志文件分成多个块,以便仅最新的日志不可用; 2)将消息记录到数据库(log4net提供了这样的界面,请参见https://www.c-sharpcorner.com/article/configure-log4net-with-database-tutorial-for-beginners/)。

答案 1 :(得分:0)

使用FileAppenderRollingFileAppender时,可以配置日志文件LockingModel。使用适当的LockingModel应该允许所需的文件访问权限。
从log4net文档(https://logging.apache.org/log4net/release/sdk/index.html

有三种内置的锁定模型:

  • FileAppender.ExclusiveLock
  • FileAppender.MinimalLock
  • FileAppender.InterProcessLock

第一个从记录开始到结束都锁定文件,第二个仅在记录每个消息时锁定最短的时间,最后一个使用命名系统范围的Mutex同步进程。

默认锁定模型为FileAppender.ExclusiveLock。

以下来自https://logging.apache.org/log4net/release/config-examples.html

的配置示例
<appender name="FileAppender" type="log4net.Appender.FileAppender">
    <file value="${TMP}\log-file.txt" />
    <appendToFile value="true" />
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    </layout>
</appender>

编辑: LockingModel公开了一个ReleaseLock方法,该方法将强制进程释放文件。要继续记录,您必须致电AcquireLock

答案 2 :(得分:0)

使用我从同事那里获得的以下代码块,我能够对日志进行只读访问(需要写访问权限才能用作电子邮件的附件):

 var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            var lines = new List<string>();
            using (var sr = new StreamReader(fs))
            {
                while(!sr.EndOfStream)
                {
                    lines.Add(sr.ReadLine());
                }
            }

我能够使用此列表并将其写入临时文件,并使用该文件发送附件,而不必担心修改log4net并危及针对同一log4net DLL的其他程序集的任何依赖关系。

感谢两个分享想法的人!