购物车服务

此服务维护用户添加到购物车中的商品。它与 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.csAddItem 函数中,向自动仪器化 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.csGetCart 函数中,添加了一个 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 跟踪 AddItemGetCart 方法的延迟,因为它们是购物车服务中的两个重要方法。

这两个方法对购物车服务至关重要,因为用户在将商品添加到购物车时,或在查看购物车后移动到结账流程之前,都不应该等待太长时间。

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 管道中,添加 MeterExemplarFilter

.AddMeter("OpenTelemetry.Demo.Cart")
.SetExemplarFilter(ExemplarFilterType.TraceBased)

要可视化 Exemplars,请导航到 Grafana https://:8080/grafana > Dashboards > Demo > Cart Service Exemplars。

Exemplars 在 95% 百分位图上显示为特殊的“菱形点”,或在热力图上显示为小方块。选择任何 exemplar 以查看其数据,包括测量时间戳、原始值以及记录时的跟踪上下文。trace_id 可用于导航到跟踪后端(在本例中为 Jaeger)。

Cart Service Exemplars

日志

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

builder.Logging
    .AddOpenTelemetry(options => options.AddOtlpExporter());

最后修改于 2025 年 3 月 4 日: [demo] 重命名 demo 服务 (#6438) (ae417344)