Зависимости касаются реализации EventSource для семантической регистрации в больших приложениях

Я работаю над большим продуктом, состоящим из трех служб Windows и нескольких обычных приложений Windows (.exe). Теперь мы хотим перейти к ETW и семантическому ведению журнала и использовать Microsoft.Diagnostics.Tracing.EventSource.

Я где-то читал, что все логически связанные части приложения должны использовать один и тот же источник событий. Это означает, что предпочтительно, чтобы мы хотели иметь в основном один EventSource для наших сервисов. Но как мы можем сделать это, не вводя зависимости практически во все сборки продукта?

Приложение в настоящее время состоит из около 70 сборок. И чтобы иметь возможность создать log-метод в EventSource, который, например, принимает enum-значение, сборка, содержащая источник события, должна ссылаться на сборку, определяющую перечисление, что означает, что определение перечисления должно быть перемещено из сборка с его использованием, возможно.exe, к чему-то, на что ссылаются все сборки.

Есть ли какой-нибудь способ иметь несколько классов, полученных из EventSource, в одном приложении, которые все еще используют один и тот же ETW EventSource? Или как можно было бы реализовать семантическую регистрацию с помощью ETW в таком сценарии, когда нежелательно вводить целую кучу новых зависимостей для создания вашего класса журнала?

3 ответа

Будь осторожен, 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);
    }
}

Теперь вы можете ввести свой класс журнала ^^

Я обычно делаю это так, чтобы была сегрегация интерфейсов, даже если они используют один экземпляр источника события. В моем ioc весь код с ISingletonDependency зарегистрирован как синглтон. Таким образом, вы можете вызывать интерфейсы с очень специфическими методами, но они все те же EventSource.

Надеюсь это поможет.

public MyCompanyEventSource: IMyCompanyEventSource, ISingletonDependency{
}
public IMyCompanyEventSource: IComponentLogger1, IComponentLogger2, IComponentLogger3{
}
public Component1{
       public Component1(IComponentLogger logger){
       }
    }

Есть три стратегии:

  1. Создайте одну сборку, которая содержит только производный класс EventSource, который определяет события для всего приложения. Добавьте ссылку на эту сборку во все необходимые проекты. Для простоты вы можете обернуть его в пакет nuget.
  2. Создайте один тестовый проект только с одним производным классом EventSource. Используйте его только для проверки. Скопируйте этот класс во все необходимые проекты. Это в основном то же решение, но без бинарных зависимостей.
  3. Создайте новый производный класс EventSource для каждого проекта, но укажите для них один и тот же атрибут Guid. В этом случае вам необходимо убедиться, что все эти источники событий имеют одинаковое объявление для перекрывающихся (с одинаковым идентификатором) событий. И в этом случае вам нужно написать какой-нибудь инструмент слияния манифеста для создания комбинированного манифеста.
Другие вопросы по тегам