diff --git a/src/TrackCenter.Api/TrackCenterApiModule.cs b/src/TrackCenter.Api/TrackCenterApiModule.cs index a4ffc9a6..8867423b 100644 --- a/src/TrackCenter.Api/TrackCenterApiModule.cs +++ b/src/TrackCenter.Api/TrackCenterApiModule.cs @@ -5,10 +5,14 @@ using Fake.Autofac; using Fake.Modularity; using FluentValidation.AspNetCore; using Hangfire; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; using TrackCenter.Application; using TrackCenter.Application.Hangfire; using TrackCenter.Domain.Extensions; using TrackCenter.Repository; +using TrackCenter.Repository.Otel; +using TrackCenter.Repository.Otel.Options; namespace TrackCenter.Api; @@ -38,7 +42,51 @@ public class TrackCenterApiModule : FakeModule .AddFakeUnitOfWorkActionFilter(); services.AddFakeSwaggerGen(); - context.Services.AddFluentValidationAutoValidation().AddFluentValidationClientsideAdapters(); + services.AddFluentValidationAutoValidation().AddFluentValidationClientsideAdapters(); + + var otelOptions = new OTelOptions() + { + EnableAspNetCore = true, + EnableHttpClient = true, + EnableSql = true + }; + configuration.GetSection("OTel").Bind(otelOptions); + ActivityHelper.InitActivitySource(otelOptions); + services.AddOpenTelemetry() + .ConfigureResource(resource => resource.AddService(otelOptions.ServiceName)) + .WithTracing(tracing => + { + switch (otelOptions.SamplerType) + { + case SamplerType.AlwaysOn: + tracing.SetSampler(new AlwaysOnSampler()); + break; + case SamplerType.AlwaysOff: + tracing.SetSampler(new AlwaysOffSampler()); + break; + case SamplerType.ParentBasedSampler: + { + Sampler childSampler = otelOptions.ChildBasedSampler switch + { + SamplerType.AlwaysOn => new AlwaysOnSampler(), + SamplerType.AlwaysOff => new AlwaysOffSampler(), + SamplerType.TraceIdRatio => + new TraceIdRatioBasedSampler(otelOptions.SamplerProbability), + _ => new AlwaysOnSampler(), + }; + tracing.SetSampler(new ParentBasedSampler(childSampler)); + } + break; + case SamplerType.TraceIdRatio: + tracing.SetSampler(new TraceIdRatioBasedSampler(otelOptions.SamplerProbability)); + break; + default: + tracing.SetSampler(new AlwaysOnSampler()); + break; + } + + tracing.AddSource(otelOptions.ServiceName); + }); services.AddCors(options => { diff --git a/src/TrackCenter.Api/appsettings.json b/src/TrackCenter.Api/appsettings.json index 121dca96..e585a74c 100644 --- a/src/TrackCenter.Api/appsettings.json +++ b/src/TrackCenter.Api/appsettings.json @@ -157,5 +157,23 @@ "PushTrackInterfaceCode": "A051", "TrackUpdateInterfaceCode": "A0400", "OrderPodPullInterfaceCode": "A059" + }, + "OTel": { + "ExporterUrl": "", + "ExporterTimeoutSeconds":10, //导出超时时间(秒) 默认 10秒 + "ServiceName": "TrackCenter.Api.Test",//服务名称 + "ServiceVersion": "1.0.0",//服务版本 + "SamplerType":"AlwaysOn",// 采样类型 默认 AlwaysOn + //枚举 + //0 AlwaysOn 总是采样 + //1 AlwaysOff 从不采样 + //2 TraceIdRatio 概率采样 与SamplerProbability 字段结合使用 + //3 ParentBasedSampler 与ChildBasedSampler 结合使用 + "SamplerProbability":0.5,// 采样率 10%上报采样 + "EnableStaticWeav":true,//启动静态编织 默认 true + "EnableAspNetCore": true,//启动AspNetCore 默认 true + "EnableHttpClient": true,//启用HTTP请求 默认 true + "EnableSql": true,//启动SQL 默认 true + "EnableSqlParameters": true //启动SQL参数,默认 false } } diff --git a/src/TrackCenter.Application/TrackCenter.Application.csproj b/src/TrackCenter.Application/TrackCenter.Application.csproj index 51326549..ba0e64a5 100644 --- a/src/TrackCenter.Application/TrackCenter.Application.csproj +++ b/src/TrackCenter.Application/TrackCenter.Application.csproj @@ -17,6 +17,8 @@ + + @@ -29,8 +31,4 @@ - - - - diff --git a/src/TrackCenter.Repository/Otel/Options/OTelOptions.cs b/src/TrackCenter.Repository/Otel/Options/OTelOptions.cs index 7f7ce7d1..fbe280b9 100644 --- a/src/TrackCenter.Repository/Otel/Options/OTelOptions.cs +++ b/src/TrackCenter.Repository/Otel/Options/OTelOptions.cs @@ -1,4 +1,9 @@ -namespace TrackCenter.Repository.Otel.Options +using System.Text.Encodings.Web; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Text.Unicode; + +namespace TrackCenter.Repository.Otel.Options { /// /// OTel options @@ -125,10 +130,27 @@ /// 用于定义tags/events等名称 /// public KeyNames KeyNames { get; set; } + /// /// 序列化参数和返回值时使用的函数 /// - public Func Serializer { get; set; } + public Func Serializer { get; set; } = obj => + { + try + { + JsonSerializerOptions options = new JsonSerializerOptions() + { + Encoder = JavaScriptEncoder.Create(UnicodeRanges.All), + ReferenceHandler = ReferenceHandler.Preserve, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull + }; + return JsonSerializer.Serialize(obj, options); + } + catch (Exception ex) + { + return obj?.ToString(); + } + }; /// /// 是否启用静态weaving /// 默认启用,如果设置为false,则不会对静态方法进行weaving