7

我正在开发一个由三个 Windows 服务和几个普通 Windows 应用程序 (.exe) 组成的大型产品。现在我们要转移到 ETW 和语义日志记录,并使用 Microsoft.Diagnostics.Tracing.EventSource。

我在某处读到应用程序的所有逻辑连接部分都应该使用相同的事件源。这意味着我们希望我们的服务有一个几乎单一的 EventSource。但是我们如何在不引入产品中几乎所有程序集之间的依赖关系的情况下做到这一点呢?

该应用程序当前包含大约 70 个程序集。为了能够在 EventSource 中创建例如接受枚举值的日志方法,包含事件源的程序集必须引用定义枚举的程序集,这意味着需要将枚举定义从使用它的程序集,也许是一个 .exe,到所有程序集引用的东西。

是否有某种方法可以在一个仍使用相同 ETW EventSource 的应用程序中从 EventSource 派生多个类?或者,在这种情况下,当不希望引入一大堆新的依赖项来创建日志类时,用 ETW 实现语义日志记录的好方法是什么?

4

3 回答 3

0

有以下三种策略:

  1. 创建一个仅包含 EventSource 派生类的程序集,该派生类为所有应用程序定义事件。将对该程序集的引用添加到所有必需的项目中。为简单起见,您可以将其包装到 nuget 包中。
  2. 仅使用一个 EventSource 派生类创建一个测试项目。仅将其用于验证目的。将此类复制到所有必需的项目中。这基本上是相同的解决方案,但没有二进制依赖关系。
  3. 为每个项目创建新的 EventSource 派生类,但为它们指定相同的 Guid 属性。在这种情况下,您需要确保所有这些事件源都具有相同的重叠(具有相同 ID)事件的声明。在这种情况下,您必须编写一些清单合并工具来生成组合清单。
于 2015-04-15T17:37:03.923 回答
0

小心,EventSource课程必须密封!如果你想使用依赖注入EventSource,有一个解决方法......

定义一个简单的接口:

// A simple interface to log what you need ...
public interface ILog
{
    void Debug(string message);

    void Info(string message);

    void Warn(string message);

    void Error(string message);

    void Error(string message, Exception exception);
}

并且实现(接口的实现必须用NonEventAttribute

[EventSource(Name = "MyLogEventsource")]
public class Log : EventSource, ILog
{
    public Log()
    {
        EventSourceAnalyzer.InspectAll(this);
    }

    [NonEvent]
    public void Debug(string message)
    {
        DebugInternal(message);
    }

    [Event(1)]
    private void DebugInternal(string message)
    {
        WriteEvent(1, message);
    }

    [NonEvent]
    public void Info(string message)
    {
        InfoInternal(message);
    }

    [Event(2)]
    private void InfoInternal(string message)
    {
        WriteEvent(2, message);
    }

    [NonEvent]
    public void Warn(string message)
    {
        WarnInternal(message);
    }

    [Event(3)]
    private void WarnInternal(string message)
    {
        WriteEvent(3, message);
    }

    [NonEvent]
    public void Error(string message)
    {
        ErrorInternal(message, "", "");
    }

    [NonEvent]
    public void Error(string message, Exception exception)
    {
        ErrorInternal(message, exception.Message, exception.ToString());
    }

    [Event(4)]
    private void ErrorInternal(string message, string exceptionMessage, string exceptionDetails)
    {
        WriteEvent(4, message, exceptionMessage, exceptionDetails);
    }
}

你现在可以注入你的日志类了^^

于 2015-12-15T10:12:10.883 回答
0

我通常这样做是为了实现接口的隔离,即使它们使用事件源的单个实例。在我的 ioc 中,所有带有 ISingletonDependency 的代码都注册为单例。因此,您可以使用非常具体的方法调用接口,但它们仍然是相同的 EventSource。

希望这可以帮助。

public MyCompanyEventSource: IMyCompanyEventSource, ISingletonDependency{
}
public IMyCompanyEventSource: IComponentLogger1, IComponentLogger2, IComponentLogger3{
}
public Component1{
       public Component1(IComponentLogger logger){
       }
    }
于 2017-04-11T10:25:47.967 回答