使用 .NETFramework 4.7.2 执行的 C# 应用程序。
我们已经使用 log4net 好几年了,并且一直很满意。不幸的是,自 2.0.12 版本以来,我们一直遇到日志未写入的问题。当我删除旧日志文件时,会创建一个新文件,但不会向该文件添加任何日志条目。
这是 App.config 中的条目:
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString" value="Log\WMS4_Server_Log.xml" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="5" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.XmlLayoutSchemaLog4j">
<locationInfo value="true" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="RollingFileAppender" />
</root>
</log4net>
任何人都可以告诉我们为什么会这样吗?
我已按照建议在 Main() 方法中添加了以下条目:
log4net.Config.XmlConfigurator.Configure();
这在一段时间内有所帮助,但现在我们又遇到了同样的问题。如果没有补救措施,我们现在准备用另一个记录器替换 log4net。 我还启用了内部日志记录,但没有得到任何提示。
下面展示了如何使用 Nuget 包 log4Net 写入日志文件。它已经使用 Nuget 包log4Net(v2.0.15)进行了测试。虽然下面的代码确实写入了日志文件,但我对 log4net 不太熟悉,因此您可能需要修改下面的代码才能获得所需格式的输出。
注意:以下内容将写入日志文件: %ProgramData%\log4netTest\Logs\log.xml。另外,您会注意到我使用 .NET Framework v4.8 进行测试,因此请根据需要更改该值。
应用程序配置:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!-- configSections MUST be the first element -->
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="${ProgramData}\log4netTest\Logs\log.xml"/>
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="5" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.XmlLayoutSchemaLog4j">
<locationInfo value="true" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
</configuration>
这是一个每 5 秒记录一次当前时间的测试项目。要重新创建我使用的测试项目:
创建一个 Windows 窗体应用程序 (.NET Framework)(名称:log4netTest)
向 Form1 添加两个按钮
Form1.cs:
using log4net;
using System;
using System.Reflection;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Security.AccessControl;
using System.Security.Principal;
namespace log4netTest
{
public partial class Form1 : Form
{
private Timer timer1 = new Timer();
private ILog log = null;
private static string logFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetExecutingAssembly().Location));
private static string logFilename = Path.Combine(logFolder, "Logs", "log.xml");
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Debug.WriteLine($"Log Folder: {logFolder}");
Debug.WriteLine($"Log Filename: {logFilename}");
//create directory if it doesn't exist
if (!Directory.Exists(logFolder))
Directory.CreateDirectory(logFolder);
//set access
DirectorySecurity logFolderSecurity = new DirectorySecurity(logFolder, AccessControlSections.Access);
logFolderSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null), FileSystemRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));
DirectoryInfo logFolderInfo = new DirectoryInfo(logFolder);
logFolderInfo.SetAccessControl(logFolderSecurity);
//initialize the log
//To use this method to configure log4net you must specify the
//'Log4NetConfigurationSectionHandler' section handler for the log4net configuration section.
//see the 'Log4NetConfigurationSectionHandler' for an example.
log4net.Config.XmlConfigurator.Configure();
log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
timer1.Interval = 5 * 1000; //5 secs
//subscribe to event
timer1.Tick += timer1_Tick;
}
private void timer1_Tick(object sender, EventArgs e)
{
log.Info($"The current time is {DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff")}");
}
private void buttonStart_Click(object sender, EventArgs e)
{
timer1.Start();
}
private void buttonStop_Click(object sender, EventArgs e)
{
timer1.Stop();
}
}
}
资源: