如何在使用WCF时按日期生成traces.svclog文件
WCF日志按日生成的实现方案
一、利用WCF内置滚动日志配置
WCF默认的XmlWriterTraceListener支持按日期滚动日志,只需在配置文件中正确设置参数即可,这是最简便的方案:
修改项目的web.config或app.config中的system.diagnostics节点,配置如下:
<system.diagnostics> <sources> <source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true"> <listeners> <add name="xml" /> </listeners> </source> <source name="System.ServiceModel.MessageLogging"> <listeners> <add name="xml" /> </listeners> </source> </sources> <sharedListeners> <add name="xml" type="System.Diagnostics.XmlWriterTraceListener" initializeData="traces_{Date}.svclog" rollOverTime="00:00:00" maxSizeRollBackups="30" traceOutputOptions="Timestamp, ActivityId" /> </sharedListeners> <trace autoflush="true" /> </system.diagnostics>
参数说明:
initializeData中的{Date}会自动替换为当前日期(格式yyyyMMdd),生成类似traces_20240520.svclog的文件rollOverTime设为00:00:00,每天零点自动切换到新日志文件maxSizeRollBackups限制保留30天的旧日志,超过数量会自动删除最早的文件autoflush="true"确保日志实时写入文件,避免缓存丢失
二、自定义TraceListener(内置配置失效时用)
如果内置滚动策略因环境或版本问题不生效,可以自定义TraceListener来完全控制日志文件的生成逻辑:
- 编写自定义TraceListener类:
public class DailyRollingXmlTraceListener : XmlWriterTraceListener { private readonly string _baseFileName; private DateTime _currentLogDate; public DailyRollingXmlTraceListener(string baseFileName) : base(GetDailyLogFileName(baseFileName)) { _baseFileName = baseFileName; _currentLogDate = DateTime.Today; } private static string GetDailyLogFileName(string baseFileName) { var dateSuffix = DateTime.Today.ToString("yyyyMMdd"); var dir = Path.GetDirectoryName(baseFileName); var fileName = $"{Path.GetFileNameWithoutExtension(baseFileName)}_{dateSuffix}{Path.GetExtension(baseFileName)}"; return Path.Combine(dir ?? "", fileName); } public override void Write(string message) { CheckAndRollLogFile(); base.Write(message); } public override void WriteLine(string message) { CheckAndRollLogFile(); base.WriteLine(message); } private void CheckAndRollLogFile() { if (DateTime.Today != _currentLogDate) { Writer.Close(); Writer.Dispose(); Writer = new XmlTextWriter(GetDailyLogFileName(_baseFileName), Encoding.UTF8); _currentLogDate = DateTime.Today; } } }
- 在配置文件中注册自定义Listener:
<system.diagnostics> <sources> <source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true"> <listeners> <add name="dailyXml" /> </listeners> </source> </sources> <sharedListeners> <add name="dailyXml" type="YourNamespace.DailyRollingXmlTraceListener, YourAssemblyName" initializeData="traces.svclog" /> </sharedListeners> <trace autoflush="true" /> </system.diagnostics>
注意替换YourNamespace和YourAssemblyName为实际的命名空间与程序集名称。
三、脚本辅助归档(兜底方案)
如果以上代码方案都无法生效,可借助Windows任务计划+PowerShell脚本实现每日归档:
- 编写PowerShell脚本
Archive-WcfLogs.ps1:
# 日志文件所在目录 $logDir = "C:\YourWcfService\Logs" # 获取日期格式 $yesterday = (Get-Date).AddDays(-1).ToString("yyyyMMdd") $serviceName = "YourWcfServiceDisplayName" # 停止服务避免文件占用 Stop-Service -Name $serviceName -Force -ErrorAction SilentlyContinue # 重命名昨日的日志文件 if (Test-Path "$logDir\traces.svclog") { Rename-Item "$logDir\traces.svclog" "traces_$yesterday.svclog" -Force } # 重启服务 Start-Service -Name $serviceName -ErrorAction SilentlyContinue # 删除30天前的旧日志 Get-ChildItem "$logDir\traces_*.svclog" | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } | Remove-Item -Force
- 在Windows任务计划中创建每日凌晨0点执行的任务,以管理员身份运行该脚本。
内容的提问来源于stack exchange,提问作者Ashitosh Kadam
相关产品推荐
相关产品推荐

