我正在为 .Net 寻找一个好的 TraceListener,它支持基于大小限制滚动日志文件。
约束
- 使用 .Net 内置的 Trace 日志记录
- 不属于某个庞大库的独立类或二进制文件
- 允许基于大小滚动日志文件
您可以使用Microsoft.VisualBasic.Logging.FileLogTraceListener,它内置于 .NET Framework 中。不要让命名空间中的 VisualBasic 吓到您,您只需引用 microsoft.visualbasic.dll 程序集,它应该可以在 C# 中正常工作。
每当我需要进行网络跟踪时,我都会将这个配置片段放在手边。我不必通过在运行时在 App.config 中添加引用来添加对 VB DLL 的显式引用来构建项目。
<system.diagnostics>
<sources>
<source name="System.Net">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
<source name="System.Net.Http">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
<source name="System.Net.Sockets">
<listeners>
<add name="System.Net"/>
</listeners>
</source>
</sources>
<switches>
<add name="System.Net" value="Verbose"/>
<add name="System.Net.Http" value="Verbose"/>
<add name="System.Net.Sockets" value="Verbose"/>
</switches>
<sharedListeners>
<add name="System.Net"
type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
traceOutputOptions="DateTime,ProcessId,ThreadId"
customLocation="c:\temp"
location="Custom"
logFileCreationSchedule="Daily"
baseFileName="NetworkTrace"/>
</sharedListeners>
<trace autoflush="true"/>
</system.diagnostics>
并在运行时添加引用
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.VisualBasic" culture="neutral" publicKeyToken="b03f5f7f11d50a3a"/>
<codeBase version="10.0.0.0" href="file://C:/Program Files (x86)/Reference Assemblies/Microsoft/Framework/.NETFramework/v4.5/Microsoft.VisualBasic.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
我是 log4net ( http://logging.apache.org/log4net/index.html )的忠实粉丝,它很容易配置并支持您想要的任何日志类型,但也可以编写自定义日志类型。
它还可以根据日志级别执行不同的操作。我们将所有消息记录到一个文本文件中,然后 Error -> Fatal 发送电子邮件
FileLogTraceListener 是一个常见的建议,但是当文件超过给定的最大大小时,它会丢弃事件或抛出异常。
我们创建了一个扩展它的类,并覆盖了 Write/WriteLine 方法。
有一个try/catch (InvalidOperationException)
,如果发生这种情况,我们调用base.Close
并重命名文件 ( FullLogFileName
),如下所示(我们需要 ,base.Close
否则我们会得到一个“文件正在使用”错误):
在一个循环中,我们在末尾添加一个数字,并查看该文件是否存在;如果没有,请使用File.Move(FullLogFileName, newFileWithNumber)
,否则我们会不断增加数字,直到找到有效的文件名。还有一个锁来确保给定的实例是线程安全的。
我使用过 Log4Net 和 Nlog。我更喜欢 NLog,但实际上一旦设置好它们,你就会忘记它们在那里(直到有东西坏了,然后你很高兴它在那里!)。互联网上应该有大量的文档
确保只安装 Logging 块,因为 EntLib 安装程序默认检查所有块。
如评论之一所述:
写入滚动文本文件。
评论
达到 maxFileSize 时使用新文件,以及 logFileCreationSchedule 指定的每日或每周。
每个文件都有一个格式为“\(-)(-).log”的名称,其中包括每日和每周轮换的本地日期,如果文件已经存在,则附加一个序列号。
我遇到过同样的问题。安全环境,不允许开源。痛苦。这对我们有用。
派生自 TextWriterTraceListener,它添加成员以获得最大日志大小、要保留的最大滚动数,并使用共享和访问设置为 ReadWrite 并设置 OpenOrCreate 的 FileStream。它还应该创建并持有一个基于文件名的互斥锁。
覆盖 TraceEvent 方法,等待互斥体,寻找流结束,调用 Write,检查大小并在必要时滚动。释放互斥锁。
对于滚动,通过文件移动和删除旋转先前的滚动,将当前文件复制到第一级滚动名称,在流上调用 SetLength(0)。所有在互斥锁内完成,但希望不会经常。这将跨进程工作,并将避免那些糟糕的 {GUID}mylog.log 东西。