贵州省网站建设_网站建设公司_门户网站_seo优化
2026/1/17 18:54:01 网站建设 项目流程

OpenTrace take a tracer instance (e.g. Jaeger) to post the metrics via UDP to the remote Jaeger instance for display

OpenTrace then can be acquired in DI manner and get the hierrchical span id everywhere you want to leverage.

In this example

First processor - Product Service will acquire OpenTrace and get the span ids which seperated in semi colon 

"fa9af85bcbcc5f09:ceb22ff39dc75f9f:fa9af85bcbcc5f09:1"

then this will be pass to rabbit mq message as property value of message.

Second Processor - Order Sevice will acquire the property via JaegerMiddleWare and resolve it to get the span id hierarchy then use it to trace whatever the operation under the same parent span id

 

 

Configuration Phase : Freqence of sending these tracing data can be configured using sampler

 

using Jaeger;
using Jaeger.Reporters;
using Jaeger.Samplers;
using Jaeger.Senders;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using OpenTracing;
using OpenTracing.Util;
using RawRabbit.Instantiation;namespace Common.Jaeger
{public static class Extensions{private static bool _initialized;public static IServiceCollection AddJaeger(this IServiceCollection services){if (_initialized){return services;}_initialized = true;var options = GetJaegerOptions(services);if (!options.Enabled){var defaultTracer = DefaultTracer.Create();services.AddSingleton(defaultTracer);return services;}services.AddSingleton<ITracer>(sp =>{var loggerFactory = sp.GetRequiredService<ILoggerFactory>();var reporter = new RemoteReporter.Builder().WithSender(new UdpSender(options.UdpHost, options.UdpPort, options.MaxPacketSize)).WithLoggerFactory(loggerFactory).Build();var sampler = GetSampler(options);var tracer = new Tracer.Builder(options.ServiceName).WithReporter(reporter).WithSampler(sampler).Build();GlobalTracer.Register(tracer);return tracer;});return services;}public static IClientBuilder UseJaeger(this IClientBuilder builder, ITracer tracer){builder.Register(pipe => pipe.Use<JaegerStagedMiddleware>(tracer));return builder;}private static JaegerOptions GetJaegerOptions(IServiceCollection services){using (var serviceProvider = services.BuildServiceProvider()){var configuration = serviceProvider.GetService<IConfiguration>();services.Configure<JaegerOptions>(configuration.GetSection("jaeger"));return configuration.GetOptions<JaegerOptions>("jaeger");}}private static ISampler GetSampler(JaegerOptions options){switch (options.Sampler){case "const": return new ConstSampler(true);case "rate": return new RateLimitingSampler(options.MaxTracesPerSecond);case "probabilistic": return new ProbabilisticSampler(options.SamplingRate);default: return new ConstSampler(true);}}}
}
Complete code for extension

For first processor - Product Service at controller level embed the span id to the context and pass over the RabbitMQ message

 For Second Processor, Order Sevice will acquire the property via JaegerMiddleWare and resolve it to get the span id hierarchy then use it to trace whatever the operation under the same parent span id

 

using Autofac;
using Common.Messages;
using Common.RabbitMQ;
using Jaeger;
using OpenTracing;
using OpenTracing.Tag;
using RawRabbit.Pipe;
using RawRabbit.Pipe.Middleware;
using System;
using System.Threading;
using System.Threading.Tasks;namespace Common.Jaeger
{public class JaegerStagedMiddleware : StagedMiddleware{private readonly ITracer _tracer;public JaegerStagedMiddleware(ITracer tracer)=> _tracer = tracer;public override string StageMarker => RawRabbit.Pipe.StageMarker.MessageDeserialized;public override Task InvokeAsync(IPipeContext context, CancellationToken token = new CancellationToken()){var correlationContext = (ICorrelationContext)context.GetMessageContext();var messageType = context.GetMessageType();using (var scope = BuildScope(messageType, correlationContext.SpanContext)){var span = scope.Span;span.Log($"Processing {messageType.Name}");try{return Next.InvokeAsync(context, token);}catch (Exception ex){span.SetTag(Tags.Error, true);span.Log(ex.Message);}}return Next.Next.InvokeAsync(context, token);}private IScope BuildScope(Type messageType, string serializedSpanContext){var spanBuilder = _tracer.BuildSpan($"processing-{messageType.Name}").WithTag("message-type", $@"{(messageType.IsAssignableTo<ICommand>() ? "command" : "event")}");if (string.IsNullOrEmpty(serializedSpanContext)){return spanBuilder.StartActive(true);}var spanContext = SpanContext.ContextFromString(serializedSpanContext);return spanBuilder.AddReference(References.FollowsFrom, spanContext).StartActive(true);}}
}
JaegerMiddleWare

 

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询