【发布时间】:2016-06-16 05:18:10
【问题描述】:
我围绕 TraceSource 类编写了一个包装器(自定义 Logger 类),以便更好地控制其他开发人员使用此自定义 Logger 和在各个级别记录数据/消息的方式。
以下是详细、错误和信息级别的实现代码。
public class Logger : ILogger
{
private const int DEF_ERROR_EVENT_ID = 2;
private const int DEF_INFORMATION_EVENT_ID = 4;
private const int DEF_DEBUG_EVENT_ID = 5;
private static TraceSource source = null;
public Logger(string nameOfComponent)
{
source = new TraceSource(nameOfComponent);
}
public void LogDebug(Type type, string methodName)
{
if (type!=null)
throw new ArgumentNullException(type.ToString());
source.TraceEvent(TraceEventType.Verbose, DEF_DEBUG_EVENT_ID, string.Format("{0}.{1}",type.ToString(),methodName));
}
public void LogError(string message, Exception ex)
{
if (String.IsNullOrEmpty(message) && ex == null)
throw new ArgumentNullException(message, ex.ToString());
source.TraceData(TraceEventType.Error, DEF_ERROR_EVENT_ID, message, ex);
}
public void LogInformation(string message)
{
if (String.IsNullOrEmpty(message))
throw new ArgumentNullException(message);
source.TraceInformation(message);
}
}
我正在 Logger 类的非默认构造函数中初始化一个静态变量“source”(鉴于此代码将在多线程环境中运行),就线程安全而言,这种做法很好?虽然 MSDN 文档说 TraceSource 是线程安全的,并且 TraceSource.TraceData()、TraceSource.TraceEvent() 等各种方法也考虑到所有写出跟踪日志的跟踪侦听器的线程安全性。因为我正在计划在我的网络应用程序中的每个类中单独实例化 Logger 类,如下所示。
private ILogger log = new Logger("name of the source/class");
在多线程环境中最好的方法是什么?将使用像 Ninject 或 Autofac 这样的 DI 容器使 Logger 类线程安全,或者我应该创建一个单例并使用它或在整个应用程序中重用它以使其成为线程安全的。如果我创建 Logger 类的单例实例,我将面临的问题是我将无法将字符串作为参数传递给 Logger 类的非默认构造函数,最终将相同的字符串传递给 TraceSource 类以知道名称源或组件的运行或运行。
你们中的一些人可能会说,为什么我要重新发明轮子并围绕 TraceSource 创建一个包装器,而不是直接使用 TraceSource。但正如我在问题开头提到的那样,我希望更好地控制作为日志发送到文件或数据库的内容。
【问题讨论】: