Razbezhkin
@Razbezhkin
программист, преподаватель

Где искать TraceId из OpenTelemetry в Jaeger и как связывать микросервисы?

Здравствуйте.
Несколько вопросов возникло при использовании OpenTelemetry в приложениях .net core
Для получения трейсов я использую Jaeger развернутый в докер.
Опирался на документацию:
https://opentelemetry.io/docs/instrumentation/net/...
https://docs.microsoft.com/ru-ru/dotnet/core/diagn...

Вопрос первый, как увидеть в Jaeger UI идентификатор трейсов?
Вот пример моего кода:

ActivitySource source = new ActivitySource(ServiceName);
Activity span = source.StartActivity(name);
string traceid = span.TraceId.ToHexString();


Трейс в Jaeger попадает, название соответствует, но в интерфейсе нигде нет того самого traceid, хотя если вбить в строке поиска по traceid, то трейс находится. вопрос, можно ли открыв трейс найти его traceid, или в Jaeger так делать не предусмотрено?

Вопрос второй, как связать трейсы из разных приложений вместе, чтобы в Jaeger они отображались вместе?
Есть статья: https://habr.com/ru/company/jugru/blog/505890/
Там есть такая картинка:
mm917vkllqx0yj77f6gxtmdmcou.png

Можно ли сделать так, чтобы в Jaeger UI отображался трейс, состоящий из спанов из разных приложений или что-бы мы не делали, Jaeger так выводить информацию не будет?

У меня уже есть метод в одном приложении который передает другому приложению traceid, в котором создается System.Diagnostics.Activity и передается в Jaeger и там появляется.
Так же есть второй метод в другом приложении, который получает traceid из первого метода, так же создает Activity, отправляет его в Jaeger и там оно появляется.

Я попытался связать второй Activity с первым таким кодом:

Activity span = source.CreateActivity(name);
span?.SetParentId(parentTraceId);
span?.Start();


В результате в поле span.Parent.TraceId находиться traceid из первого метода, в span.TraceId сгенерировался новый traceid и в Jaeger UI отображаются два не связанных друг с другом трейса.

Итак, животрепещущий вопрос: Можно ли все таки сделать так чтобы мы видели в Jaeger один Трейс, который бы состоял из активностей из разных приложений, или это в Jaeger в принципе не возможно?
Ну и если можно то как в классах SystemDiagnostics устанавливать эту связь?

Спасибо за внимание.
  • Вопрос задан
  • 1005 просмотров
Решения вопроса 1
Razbezhkin
@Razbezhkin Автор вопроса
программист, преподаватель
В общем, не все так просто как казалось.
Пришлось скачать исходники opentelemetry https://github.com/open-telemetry/opentelemetry-dotnet и посмотреть, как устроено распространение трассировочной информации в инструментарии AspNetCore.

Сохранение, передача и восстановление TraceID (и доп информации) называется Propogation.
В пакете OpenTelemetry Есть специальный класс:
OpenTelemetry.Context.Propagation.Propagators
Который возвращает этих пропогаторов с помощью которых производиться внедрение и извлечение контекстной информации (информации о трассировке).

Чтобы куда-нибудь внедрить данные о трассировке, можно использовать примерно такой код:

//достаем текстового распространителя
var textMapPropagator = Propagators.DefaultTextMapPropagator;
//формируем контекст распространения
var propContext = new OpenTelemetry.Context.Propagation.PropagationContext(Activity.Current.Context, Baggage.Current);
//этот метод вызывает для каждого необходимого значения их контекста распространения ваш же метод, который сохраняет пару ключ-значения для последующего восстановления
textMapPropagator.Inject(propContext,context, (ctx, name, val) =>
{
    ctx.Headers.Set(name,val);
});


На другой стороне нужно контекст трассировки восстановить. код примерно такой:

//извлекаем из среды распространяемую трейс-информацию
        var propagator = Propagators.DefaultTextMapPropagator;
        PropagationContext propagationContext = propagator.Extract(default, context,
            (ctx, name) => { return new string[] { ctx.Headers.Get<string>(name) }; });

        if (propagationContext.ActivityContext.IsValid())
        {
            //формируем новый спан.
            newOne = new Activity("Consumer");
            newOne.SetParentId(propagationContext.ActivityContext.TraceId,
                propagationContext.ActivityContext.SpanId,
                propagationContext.ActivityContext.TraceFlags);
            newOne.TraceStateString = propagationContext.ActivityContext.TraceState;
            newOne.Start();
            newOne.IsAllDataRequested = false;

            Baggage.Current = propagationContext.Baggage;
        }


в результате контекст трассировки восстанавливается и в Jaeger попадает в связанном виде.
Единственная проблема в том, что именно этот Span не сохраняется (хотя все последующие в цепочке - да) и появляется Warning вида: "invalid parent span IDs=b3f757a84de75eda; skipping clock skew adjustment"
Что с ним делать - пока не знаю. чего-то все такие не хватает
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы