Как добавить EventSource в веб-приложение

Наконец-то мы правильно настроили EventSource и ElasticSearch в нашем кластере сервисной фабрики. Теперь, когда у нас есть это, мы хотим добавить EventSources в наши веб-приложения, которые взаимодействуют с нашими приложениями Service Fabric, чтобы мы могли просматривать все события (журналы приложений) в одном месте и фильтровать/запрашивать через Kibana.

Наша проблема, по-видимому, связана с различиями между приложением Service Fabric, которое является исполняемым файлом, и веб-приложением .NET 4.6 (не .net CORE), которое не имеет состояния. В Service Fabric мы размещаем оператор using, который создает экземпляр конвейера в Program.cs, и устанавливаем бесконечный спящий режим.

private static void Main()
{
        try
        {
            using (var diagnosticsPipeline = ServiceFabricDiagnosticPipelineFactory.CreatePipeline("CacheApp-CacheAPI-DiagnosticsPipeline"))
            {
                ServiceEventSource.Current.ServiceTypeRegistered(Process.GetCurrentProcess().Id, typeof(Endpoint).Name);
                // Prevents this host process from terminating so services keeps running. 
                Thread.Sleep(Timeout.Infinite);
            }

Как это сделать в веб-приложении? Это конвейерный код, который мы используем для реализации EventSource без ServiceFabric. Вот что мы используем:

using (var pipeline = DiagnosticPipelineFactory.CreatePipeline("eventFlowConfig.json"))
    {
        IEnumerable ie = System.Diagnostics.Tracing.EventSource.GetSources();

        ServiceEventSource.Current.Message("initialize eventsource");

    } 

Мы можем видеть конвейер и отправлять события в ElasticSearch из оператора using, но не за его пределами. Итак, вопрос:

  1. как/где мы размещаем наш конвейер, используя инструкцию для веб-приложения?
  2. Нужно ли нам создавать и уничтожать конвейер каждый раз, когда мы регистрируемся, или есть способ повторно использовать этот конвейер для веб-событий без сохранения состояния? Казалось бы, это будет очень дорого и повредит производительности. Может быть, мы можем кэшировать конвейер?

Это суть, дайте мне знать, если вам нужны разъяснения. Я вижу много документации для клиентских приложений, но не так много для веб-приложений.

Спасибо, Грег

ОБНОВЛЕНИЕ С КОДОМ РЕШЕНИЯ

конвейер DiagnosticPipeline;

protected void Application_Start(Object sender, EventArgs e)
{
    try
    {
        pipeline = DiagnosticPipelineFactory.CreatePipeline("eventFlowConfig.json");   
        IEnumerable ie = System.Diagnostics.Tracing.EventSource.GetSources();
        AppEventSource.Current.Message("initialize eventsource");

    }
}

protected void Application_End(Object sender, EventArgs e)
{
    pipeline.Dispose();
}

person gperrego    schedule 31.03.2017    source источник


Ответы (1)


Предполагая, что ASP.NET Core, самым простым способом инициализации конвейера EventFlow будет метод Program.cs Main(), например:

public static void Main(string[] args)
{
    using (var pipeline = DiagnosticPipelineFactory.CreatePipeline("eventFlowConfig.json"))
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .UseApplicationInsights()
            .Build();

            host.Run();
    }
}

Это использует тот факт, что host.Run() будет блокироваться до тех пор, пока сервер не будет выключен, поэтому конвейер будет существовать в течение времени, когда запросы принимаются и обслуживаются.

В зависимости от веб-фреймворка, который вы используете, все может отличаться. Например. если тот, который вы используете, предлагает перехватчики «настройки» и «очистки», вы можете создать диагностический конвейер на этапе установки (и сохранить ссылку на него в какой-либо переменной-члене), а затем избавиться от него на этапе очистки. Например, в классическом ASP.NET вы должны поместить код в global.asax.cs и использовать методы Application_OnStart и Application_OnEnd. См. Экземпляры приложений, события приложений и состояние приложения в ASP.NET для получения подробной информации.

Как вы сказали, создавать экземпляр конвейера каждый раз, когда обслуживается запрос, довольно неэффективно. На самом деле нет веских причин для этого.

person Karol Z    schedule 31.03.2017
comment
спасибо, но это не .net CORE, это более старое приложение веб-форм, размещенное в IIS. В этих приложениях нет файла main. Может быть, я мог бы использовать global.asax? – - person gperrego; 31.03.2017
comment
Да, я бы попробовал global.asax. Я добавил некоторые детали к исходному ответу. - person Karol Z; 03.04.2017
comment
Значит, тогда мы не будем использовать оператор using? вид Application_Start действует как наш оператор использования, и мы помещаем переменную прямо в on Start? var pipe = DiagnosticPipelineFactory.CreatePipeline(eventFlowConfig.json); Затем удалите переменную Application_End. Попробуйте сейчас - person gperrego; 04.04.2017
comment
ВуХуу!!!! Это сработало. Мне пришлось создать глобальную переменную над application_start, а затем просто назначить конвейер этой глобальной переменной. Затем я смог использовать конвейер на другой странице. Я вызываю метод dispose для объекта конвейера в событии application_end. - person gperrego; 04.04.2017