OpenTracing в ядре .NET без зависимости от конкретной библиотеки решений

Для входа в наши приложения микросервисов мы просто регистрируемся на stdout / console, а драйвер ведения журнала докеров обрабатывает и перенаправляет эти журналы куда-нибудь, например. gelf / logstash, fluentd и т. д. В основном мы следуем 12-факторному руководству по ведению журнала. Это означает, что разработчикам, работающим над кодом приложения, не нужно ничего знать о базовом решении для ведения журнала (например, Elasticsearch, Graylog, Splunk и т. Д.) - это полностью проблема эксплуатации / конфигурации. Теоретически мы должны иметь возможность изменить базовое решение для ведения журнала без каких-либо изменений кода.

Я бы хотел что-то подобное для трассировок, и мои исследования привели меня к OpenTracing. Разработчикам не нужно знать базовое решение для трассировки (например, Jaeger, Zipkin, Elastic APM и т. Д.) И сведения о ведении журнала; теоретически мы должны иметь возможность изменить лежащее в основе решение трассировки без каких-либо изменений кода.

Я успешно получил POC ядра .NET, отправляющий трассировки в Jaeger с помощью opentracing / opentracing-csharp и библиотеки jaegertracing / jaeger-client-csharp.

Я все еще пытаюсь полностью разобраться в OpenTracing, но мне интересно, есть ли способ отправлять трассировки в API, совместимый с OpenTracing, без необходимости жестко зависеть от конкретного решения, такого как Jaeger (то есть jaeger-client -csharp библиотека). Насколько я понимаю, OpenTracing - это просто стандарт. Разве я не могу просто настроить конечную точку OpenTracing с некоторыми параметрами выборки без использования библиотеки jaeger-client-csharp? Или дело в том, что jaeger-client-csharp на самом деле не специфичен для Jaeger и действительно может отправлять трассировки в любой API OpenTracing?

Пример конфигурации, показанный ниже, в котором используется клиентская библиотека jaeger:

services.AddOpenTracing();

if (appSettings.TracerEnabled)
{
   services.AddSingleton(serviceProvider =>
   {
      var loggerFactory = new LoggerFactory();
      var config = Jaeger.Configuration.FromEnv(loggerFactory);

      var tracer = config.GetTracer();

      GlobalTracer.Register(tracer);

      return tracer;
   });
}

person Ryan.Bartsch    schedule 03.05.2019    source источник


Ответы (1)


OpenTracing - это набор стандартных API, которые последовательно моделируют и описывают поведение распределенных систем)

OpenTracing не описывает, как собирать, сообщать, хранить или представлять данные взаимосвязанных трасс и участков. Это детали реализации (например, jaeger или волновой фронт).

jaeger-client-csharp очень специфичен для jaeger. Но есть одно исключение, называемое zipkin, которое в свою очередь, не полностью совместим с OpenTracing, даже если он имеет аналогичные условия.

Если вас устраивает opentracing-contrib / csharp-netcore (надеюсь, вы используете эта библиотека), то, если вы хотите добиться «отсутствия изменения кода» (в целевой микросервисе) для настройки подсистемы трассировки, вам следует использовать некоторую модель плагина.

Хорошие новости: aspnetcore имеет концепцию размещенные стартовые сборки, которые позволяют настраивать систему трассировки. Итак, у вас может быть некоторая библиотека с именем JaegerStartup, в которой вы реализуете IHostedStartup следующим образом:

public class JaegerStartup : IHostingStartup
{
    public void Configure(IWebHostBuilder builder)
    {
        builder.ConfigureServices((ctx, services) =>
        {
            services.AddOpenTracing();

            if (ctx.Configuration.IsTracerEnabled()) // implement it by observing your section in configuration.
            {
                services.AddSingleton(serviceProvider =>
                {
                    var loggerFactory = new LoggerFactory();
                    var config = Jaeger.Configuration.FromEnv(loggerFactory);

                    var tracer = config.GetTracer();

                    GlobalTracer.Register(tracer);

                    return tracer;
                });
            }
        });
    }
}

Когда вы решили переключить систему трассировки - вам нужно создать другую библиотеку, которая может загружаться автоматически, и целевой код микросервиса не будет затронут.

person stukselbax    schedule 05.08.2019
comment
Спасибо за отличный ответ. IHostingStartup - лучший подход, чем то, что у меня есть сейчас - немного напоминает мне MEF. В конечном итоге я хотел бы иметь возможность переключаться между трассировщиками, совместимыми с Open-Tracing / Telemetry (например, ElasticAPM, Jaeger и т. Д.), С помощью только config. Поправьте меня, если я ошибаюсь, но подход IHostingStartup все равно потребует повторной компиляции (или, по крайней мере, пересборки образа докера). В идеале замена трассировщика должна быть проблемой OPS. - person Ryan.Bartsch; 06.08.2019
comment
Также; да - с использованием библиотеки opentracing-contrib / csharp-netcore :) Думаю, что мне бы хотелось, так это некоторая стандартизация для API отчетности. Это означало бы, что вы могли бы использовать любую (OT-совместимую) клиентскую библиотеку / агент, которые хотите, например elastic / apm-agent-dotnet, а лежащее в основе решение трассировки может быть чем-то другим, например Datadog или Wavefront и т. Д. Я подозреваю, что OpenTracing не на этом уровне зрелости или не пытается решить эту проблему ... - person Ryan.Bartsch; 06.08.2019
comment
Вам не нужно перекомпилировать или пересобирать. Вам нужно создать новую отдельную библиотеку (только здесь вам нужно скомпилировать), которая содержит логику внедрения для нового трассировщика. Когда у вас будет новая библиотека, ребята из OPS возьмут новую и изменят переменная среды с именем ASPNETCORE_HOSTINGSTARTUPASSEMBLIES. Reporting API - это деталь реализации. Вы должны использовать DiagnosticsSource ИЛИ ITracer напрямую для сбора трассировок и интервалов и создания отчетов. - person stukselbax; 06.08.2019