На стороне отправителя я извлекаю Activity.id (который содержит как Traceid, так и Spanid), сохраняю его в Заголовок сообщения и отправить сообщение. Используйте SetParentId для прохождения строки трассировки (например, «00-trakeid-spanid-flags»). < /p>
< /li>
< /ul>
В локальных тестах , все работает отлично. Однако в Pre-Prod, где сообщения отправляются и используются различными службами, следы кажутся правильными индивидуально, но не образуют плавную иерархию. В частности: < /p>
корневая активность Service 1 и ее дети отображаются правильно. < /P>
< /li>
< li> корневая активность Service 2 и ее дети отображаются правильно. В соответствии с деревом службы 1. Действия, созданные в том же контексте, не используют SetParentId; Я создаю новое занятие, в то время как родительский не утилизируется. Я использую последние версии .NET, C#, OpenTeLemetry и Confluent.kafka. < /P>
OTEL config: < /p>
Код: Выделить всё
services.AddOpenTelemetry().ConfigureResource(delegate (ResourceBuilder r)
{
r.AddService(serviceName, environment, serviceVersion);
}).WithTracing(delegate (TracerProviderBuilder builder)
{
builder
.SetErrorStatusOnException()
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddAWSInstrumentation()
.AddRedisInstrumentation()
.AddSqlClientInstrumentation()
.AddGrpcClientInstrumentation()
.AddOtlpExporter()
.AddSource("*")
.SetSampler();
})
.WithMetrics(delegate (MeterProviderBuilder builder)
{
//metrics
});
Код: Выделить всё
//Sample code of how activities are created
internal class MyClass
{
private readonly ActivitySource _activitySource = new(nameof(MyClass));
internal Confluent.Kafka.Message SaveTraceIntoMessage()
{
return new Message()
{
Key = "message.Key",
Value = JsonSerializer.Serialize(new
{
Headers = new []
{
new string[] { "traceparent", Activity.Current.Id }
}
})
};
}
//this would be in another service, of course
internal void ReceiveMessage()
{
var anotherActivitySource = new ActivitySource("Receiver");
var activity = anotherActivitySource.CreateActivity("Receive",ActivityKind.Consumer);
// pretend this is a consumer
var consumeMessage = new Message();
var pretendIDeserializedTheValueofMessage = consumeMessage.Value;
activity.SetParentId(pretendIDeserializedTheValueofMessage);
activity.Start();
//Do Some work
activity.Stop();
}
internal void ProduceMessage()
{
using var source = _activitySource.StartActivity("Produce");
Confluent.Kafka.IProducer? producer = GetProducer();
Confluent.Kafka.Message message = SaveTraceIntoMessage();
producer!.Value.Produce(message);
}
private Confluent.Kafka.IProducer GetProducer()
{
//return some producer
return null;
}
}

Подробнее здесь: https://stackoverflow.com/questions/793 ... -only-in-l