【发布时间】:2014-05-03 14:00:28
【问题描述】:
我正在探索将基于 TraceSource 的日志记录添加到我的 ASP.NET 应用程序中。我需要有选择地控制不同代码组件的 SourceLevels 的能力,因此需要多个源。所有 TraceSource 实例都将写入单个 FileLogTraceListener 派生侦听器。
这种策略会在多线程环境中产生性能/并发访问问题吗? 从 MSDN 描述中,TraceSource 和 FileLogTraceListener 似乎都是线程安全的。有没有人有相反的经验?
在这种情况下,是通过 app.config / web.config 中的<sharedListers> 添加侦听器而不是像我在下面的代码中那样以编程方式添加侦听器吗?
我使用了这个完美运行的测试代码 - 写出预期的日志条目数。在我将这个策略部署到生产环境之前,我只是想要一些指导。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using Microsoft.VisualBasic.Logging;
namespace SourcesListeners
{
class Program
{
[STAThread]
static void Main()
{
const string baseFileName = @"test-log";
var threads = 10*Environment.ProcessorCount;
const int iterationsPerThread = 4000;
var listener = new DailyRollingFileListener(@".\", baseFileName);
{
Parallel.For(0, threads, i =>
{
var source = new TraceSource(string.Format("source-{0}", i), SourceLevels.All);
source.Listeners.Clear();
source.Listeners.Add(listener);
source.TraceEvent(TraceEventType.Information, 0, "Created");
for (var k = 0; k < iterationsPerThread; ++k)
{
source.TraceEvent(TraceEventType.Information, 0, "thread: {0}, iteration: {1}", i, k);
}
});
}
}
class DailyRollingFileListener : FileLogTraceListener
{
public DailyRollingFileListener(
string customLocation, string baseFileName,
bool autoFlush = true)
{
CustomLocation = customLocation;
BaseFileName = baseFileName;
AutoFlush = autoFlush;
LogFileCreationSchedule = LogFileCreationScheduleOption.Daily;
Append = false;
MaxFileSize = 40*1024*1024;
}
public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message)
{
var entry = string.Format("{0:yyyy-MM-dd hh:mm:ss.fff}Z {1,4} {2,-5} {3} {4}",
eventCache.DateTime,
eventCache.ThreadId,
GetSeverity(eventType),
source,
message);
base.WriteLine(entry);
}
public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args)
{
var message = args != null ? string.Format(format, args) : format;
if (eventCache != null)
{
TraceEvent(eventCache, source ?? string.Empty, eventType, id, message);
}
else
{
base.WriteLine(string.Format("{0} {1} {2}", GetSeverity(eventType), source ?? string.Empty, message));
}
}
private static string GetSeverity(TraceEventType eventType)
{
string value;
return SeverityLevel.TryGetValue(eventType, out value) ? value : eventType.ToString().ToUpper();
}
private static readonly Dictionary<TraceEventType, string> SeverityLevel =
new Dictionary<TraceEventType, string>
{
{TraceEventType.Critical, "FATAL"},
{TraceEventType.Error, "ERROR"},
{TraceEventType.Warning, "WARN "},
{TraceEventType.Information, ""},
{TraceEventType.Verbose, "DEBUG"},
{TraceEventType.Start, "ENTRY"},
{TraceEventType.Stop, "EXIT "},
};
}
}
}
【问题讨论】:
标签: c# .net multithreading logging system.diagnostics