【问题标题】:How to make wrapper around TraceSource class thread safe如何使 TraceSource 类线程安全的包装器
【发布时间】: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。但正如我在问题开头提到的那样,我希望更好地控制作为日志发送到文件或数据库的内容。

【问题讨论】:

    标签: c# .net logging trace


    【解决方案1】:

    我还不能发表评论——所以我会问你为什么要创建自定义记录器而不是使用 NLog。如果你这样做了,那么 NLog 中的静态日志实例是线程安全的:

    private static Logger logger = LogManager.GetLogger("MyClassName");
    

    由于记录器是线程安全的,您只需创建一次记录器并将其存储在静态变量中。

    在此处查看更多信息:https://github.com/NLog/NLog/wiki/Tutorial

    Nlog 具有高度可配置性,似乎适合您描述的用例。

    HTH

    【讨论】:

    • 嗯,问题是我们查看了 Log4Net、Nlog 等。但是这些开箱即用的记录器都没有将日志插入数据库。他们所做的只是将日志写入硬盘上的文件中。如果我错了,请纠正我,因为这就是我对这些记录器的理解。为了实现我需要实现的目标,我还编写了一个自定义跟踪侦听器,它负责将日志插入数据库
    • NLog 可以写入数据库。以下是一些信息:github.com/NLog/NLog/wiki/Database-target
    • 很酷,但我仍然被指示编写自定义记录器和自定义跟踪侦听器。所以我需要坚持我被要求做的事情。
    猜你喜欢
    • 1970-01-01
    • 2012-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多