如何以编程方式强制 log4net 释放日志文件以便可以访问?
How to programmatically force log4net to release log file so it can be accessed?
我需要在大型流程执行后发送一封电子邮件,并将日志文件作为附件,以便用户可以识别任何问题。我们使用 log4net 来处理我们所有的日志记录,但我无法让 log4net 发布文件以便将其添加为附件。
到目前为止,我遵循了这个问题的结果: 关于将 appender 阈值设置为 "Off",但由于 DLL 未释放日志文件,我继续收到异常。我可以在调试器中验证 appender 实际上在 "Off" 中,但进程资源管理器确认我的 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;
}
}
}
任何关于如何强制发布此日志的想法都将非常有帮助。谢谢
日志已打开以供写入,因此释放锁定的唯一方法是停止应用程序。您确实有选择:1)使用 maximumFileSize 设置将日志文件分成块,以便只有最近的日志不可用; 2) 将消息记录到数据库(log4net提供了这样的接口,见https://www.c-sharpcorner.com/article/configure-log4net-with-database-tutorial-for-beginners/)。
使用FileAppender
或RollingFileAppender
时,可以配置日志文件LockingModel
。使用适当的 LockingModel
应该允许所需的文件访问权限。
来自 log4net 文档 (https://logging.apache.org/log4net/release/sdk/index.html)
内置三种锁定模型:
- FileAppender.ExclusiveLock
- FileAppender.MinimalLock
- FileAppender.InterProcessLock
第一个从记录开始到结束锁定文件,第二个仅在记录每条消息时锁定最短的时间,最后一个使用命名的系统范围互斥体同步进程。
默认锁定模型是 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
.
使用我从同事那里得到的以下代码块,我能够 read-only 访问日志(需要写入权限才能用作电子邮件中的附件):
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 的其他程序集的任何依赖项。
感谢分享想法的两位!
我需要在大型流程执行后发送一封电子邮件,并将日志文件作为附件,以便用户可以识别任何问题。我们使用 log4net 来处理我们所有的日志记录,但我无法让 log4net 发布文件以便将其添加为附件。
到目前为止,我遵循了这个问题的结果:
这是我从链接问题中得到的方法:
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;
}
}
}
任何关于如何强制发布此日志的想法都将非常有帮助。谢谢
日志已打开以供写入,因此释放锁定的唯一方法是停止应用程序。您确实有选择:1)使用 maximumFileSize 设置将日志文件分成块,以便只有最近的日志不可用; 2) 将消息记录到数据库(log4net提供了这样的接口,见https://www.c-sharpcorner.com/article/configure-log4net-with-database-tutorial-for-beginners/)。
使用FileAppender
或RollingFileAppender
时,可以配置日志文件LockingModel
。使用适当的 LockingModel
应该允许所需的文件访问权限。
来自 log4net 文档 (https://logging.apache.org/log4net/release/sdk/index.html)
内置三种锁定模型:
- FileAppender.ExclusiveLock
- FileAppender.MinimalLock
- FileAppender.InterProcessLock
第一个从记录开始到结束锁定文件,第二个仅在记录每条消息时锁定最短的时间,最后一个使用命名的系统范围互斥体同步进程。
默认锁定模型是 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
.
使用我从同事那里得到的以下代码块,我能够 read-only 访问日志(需要写入权限才能用作电子邮件中的附件):
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 的其他程序集的任何依赖项。
感谢分享想法的两位!