使用zipKin构建NetCore分布式链路跟踪 (2)

接下来在Startup中引入ZipKin

public void ConfigureServices(IServiceCollection services) { // 注入Rpc //AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); //services.AddGrpcClient<HelloServer.HelloServerClient>((p, o) => //{ // o.Address = new Uri("http://127.0.0.1:3848"); //}); //.AddHttpMessageHandler(provider => TracingHandler.WithoutInnerHandler("RpcService")); services.AddControllers(); services.AddZipKin(); services.AddSingleton<IDiagnosticSource, HttpDiagnosticSourceDemo>(); services.AddHttpClient("webApi", client => { client.BaseAddress = new Uri($"http://localhost:5001"); }); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "SimpleZipKin", Version = "v1" }); }); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory, IHostApplicationLifetime lifetime) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseSwagger(); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "SimpleZipkin v1")); } Configuration.GetSection("ExceptionLess").Bind(ExceptionlessClient.Default.Configuration); ExceptionlessClient.Default.Configuration.SetDefaultMinLogLevel(Exceptionless.Logging.LogLevel.Debug); app.UseZipKin(lifetime, loggerFactory, "SimpleZip", "http://127.0.0.1:9411");//SimpleZip修改为对应的应用名称,127.0.0.1地址切换为自己的zipkin地址 app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }

接下来创建对应的Controller

[Route("/api/Home")] public class HomeController : Controller { private readonly IHttpClientFactory _httpClientFactory; private readonly ILogger _logger; /// <summary> /// 构造函数 /// </summary> /// <param></param> /// <param></param> public HomeController(IHttpClientFactory httpClientFactory, ILogger<HomeController> logger) { _httpClientFactory = httpClientFactory; //_helloServerClient = helloServerClient; _logger = logger; } [HttpGet("GetZipKin")] public async Task<string> GetZipKin() { _logger.InformationToException($@"这里是SimpleZipKinApi"); var httpClient = _httpClientFactory.CreateClient("webApi"); var httpResult = await httpClient.GetAsync($"api/order/getorder"); var result = await httpResult.Content.ReadAsStringAsync(); return result; } }

最后在appsettings.json中加入对应的Exceplesstionless配置

"ExceptionLess": { "ApiKey": "****************************", "ServerUrl": "http://127.0.0.1:5000" }

OrderApi、WebApi如法炮制,修改对应的请求链路信息

接下来我们使用DiagnosticAdapter做链路记载,在公共类库中创建HttpDiagnosticListener类
DiagnosticSource是Runtime层提供,应用层可以通过它与系统集成、事件日志、以及性能计数器进行交互。
DiagnosticSource官方介绍:https://docs.microsoft.com/zh-cn/dotnet/api/system.diagnostics.diagnosticsource?view=net-5.0
关于DiagnosticSource设计参考原有yi念之间大佬的文章:https://www.cnblogs.com/wucy/p/13532534.html

public class HttpDiagnosticSourceDemo : IDiagnosticSourceDemo { public string DiagnosticName => "HttpDiagnosticSourceDemo"; private ClientTrace _clientTrace; private readonly IInjector<HttpHeaders> _injector = Propagations.B3String.Injector<HttpHeaders>((carrier, key, value) => carrier.Add(key, value)); [DiagnosticName("System.Net.Http.Request")] public void HttpRequest(HttpRequestMessage request) { _clientTrace = new ClientTrace("simpleZipKin", request.Method.Method); if (_clientTrace.Trace != null) { _injector.Inject(_clientTrace.Trace.CurrentSpan, request.Headers); } } [DiagnosticName("System.Net.Http.Response")] public void HttpResponse(HttpResponseMessage response) { if (_clientTrace.Trace != null) { _clientTrace.AddAnnotation(Annotations.Tag(zipkinCoreConstants.HTTP_PATH, response.RequestMessage.RequestUri.LocalPath)); _clientTrace.AddAnnotation(Annotations.Tag(zipkinCoreConstants.HTTP_METHOD, response.RequestMessage.Method.Method)); _clientTrace.AddAnnotation(Annotations.Tag(zipkinCoreConstants.HTTP_HOST, response.RequestMessage.RequestUri.Host)); if (!response.IsSuccessStatusCode) { _clientTrace.AddAnnotation(Annotations.Tag(zipkinCoreConstants.HTTP_STATUS_CODE, ((int)response.StatusCode).ToString())); } } } [DiagnosticName("System.Net.Http.Exception")] public void HttpException(HttpRequestMessage request, Exception exception) { } }

IDiagnosticSourceDemo接口信息如下:

public interface IDiagnosticSourceDemo { string DiagnosticName { get; } }

HttpDiagnosticSourceObserver方法如下:

public class HttpDiagnosticSourceObserver : IObserver<DiagnosticListener> { private IEnumerable<IDiagnosticSourceDemo> _diagnosticSourceDemo; public HttpDiagnosticSourceObserver (IEnumerable<IDiagnosticSourceDemo> diagnosticSourceDemo) { _diagnosticSourceDemo= diagnosticSourceDemo; } public void OnCompleted() { } public void OnError(Exception error) { } public void OnNext(DiagnosticListener listener) { var diagnosticSource= _diagnosticSourceDemo.FirstOrDefault(i => i.DiagnosticName == listener.Name); if (traceDiagnostic != null) { //适配订阅 listener.SubscribeWithAdapter(diagnosticSource); } } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzsyxs.html