购物车服务
此服务维护用户添加到购物车中的商品。它与 Valkey 缓存服务交互,以便快速访问购物车数据。
注意 .NET 的 OpenTelemetry 使用
System.Diagnostic.DiagnosticSource库作为其 API,而不是标准 OpenTelemetry API(用于 Traces 和 Metrics)。Microsoft.Extensions.Logging.Abstractions库用于 Logs。
追踪
初始化追踪
.NET 依赖注入容器中配置了 OpenTelemetry。AddOpenTelemetry() 构建器方法用于配置所需的仪器库、添加导出器和设置其他选项。导出器和资源属性的配置通过环境变量完成。
Action<ResourceBuilder> appResourceBuilder =
resource => resource
.AddContainerDetector()
.AddHostDetector();
builder.Services.AddOpenTelemetry()
.ConfigureResource(appResourceBuilder)
.WithTracing(tracerBuilder => tracerBuilder
.AddSource("OpenTelemetry.Demo.Cart")
.AddRedisInstrumentation(
options => options.SetVerboseDatabaseStatements = true)
.AddAspNetCoreInstrumentation()
.AddGrpcClientInstrumentation()
.AddHttpClientInstrumentation()
.AddOtlpExporter());
为自动仪表化的 Span 添加属性
在自动仪器化代码执行期间,您可以从上下文中获取当前 span(activity)。
var activity = Activity.Current;
使用 activity 对象上的 SetTag 来为 span(activity)添加属性(.NET 中的标签)。在 services/CartService.cs 的 AddItem 函数中,向自动仪器化 span 添加了几个属性。
activity?.SetTag("app.user.id", request.UserId);
activity?.SetTag("app.product.quantity", request.Item.Quantity);
activity?.SetTag("app.product.id", request.Item.ProductId);
添加跨度事件
使用 activity 对象上的 AddEvent 来添加 span(activity)事件。在 services/CartService.cs 的 GetCart 函数中,添加了一个 span 事件。
activity?.AddEvent(new("Fetch cart"));
指标
初始化指标
与配置 OpenTelemetry Traces 类似,.NET 依赖注入容器需要调用 AddOpenTelemetry()。此构建器配置所需的仪器库、导出器等。
Action<ResourceBuilder> appResourceBuilder =
resource => resource
.AddContainerDetector()
.AddHostDetector();
builder.Services.AddOpenTelemetry()
.ConfigureResource(appResourceBuilder)
.WithMetrics(meterBuilder => meterBuilder
.AddMeter("OpenTelemetry.Demo.Cart")
.AddProcessInstrumentation()
.AddRuntimeInstrumentation()
.AddAspNetCoreInstrumentation()
.SetExemplarFilter(ExemplarFilterType.TraceBased)
.AddOtlpExporter());
Exemplars
在购物车服务中,使用基于跟踪的示例过滤器配置了 Exemplars,这使得 OpenTelemetry SDK 能够将示例附加到指标。
首先,它创建了一个 CartActivitySource、一个 Meter 和两个 Histograms。Histogram 跟踪 AddItem 和 GetCart 方法的延迟,因为它们是购物车服务中的两个重要方法。
这两个方法对购物车服务至关重要,因为用户在将商品添加到购物车时,或在查看购物车后移动到结账流程之前,都不应该等待太长时间。
private static readonly ActivitySource CartActivitySource = new("OpenTelemetry.Demo.Cart");
private static readonly Meter CartMeter = new Meter("OpenTelemetry.Demo.Cart");
private static readonly Histogram<long> addItemHistogram = CartMeter.CreateHistogram<long>(
"app.cart.add_item.latency",
advice: new InstrumentAdvice<long>
{
HistogramBucketBoundaries = [ 500000, 600000, 700000, 800000, 900000, 1000000, 1100000 ]
});
private static readonly Histogram<long> getCartHistogram = CartMeter.CreateHistogram<long>(
"app.cart.get_cart.latency",
advice: new InstrumentAdvice<long>
{
HistogramBucketBoundaries = [ 300000, 400000, 500000, 600000, 700000, 800000, 900000 ]
});
请注意,还定义了自定义存储桶边界,因为默认值不适用于购物车服务的微秒结果。
一旦定义了变量,就会像下面这样使用 StopWatch 跟踪每个方法的执行延迟
var stopwatch = Stopwatch.StartNew();
(method logic)
addItemHistogram.Record(stopwatch.ElapsedTicks);
为了将所有内容连接起来,在 Traces 管道中,需要添加创建的源。(已在上面的代码片段中显示,但在此处添加以供引用)
.AddSource("OpenTelemetry.Demo.Cart")
并且,在 Metrics 管道中,添加 Meter 和 ExemplarFilter。
.AddMeter("OpenTelemetry.Demo.Cart")
.SetExemplarFilter(ExemplarFilterType.TraceBased)
要可视化 Exemplars,请导航到 Grafana https://:8080/grafana > Dashboards > Demo > Cart Service Exemplars。
Exemplars 在 95% 百分位图上显示为特殊的“菱形点”,或在热力图上显示为小方块。选择任何 exemplar 以查看其数据,包括测量时间戳、原始值以及记录时的跟踪上下文。trace_id 可用于导航到跟踪后端(在本例中为 Jaeger)。

日志
日志在 .NET 依赖注入容器中,在 LoggingBuilder 级别通过调用 AddOpenTelemetry() 进行配置。此构建器配置所需的选项、导出器等。
builder.Logging
.AddOpenTelemetry(options => options.AddOtlpExporter());