使用示例

了解如何使用示例将指标与 OpenTelemetry .NET 中的跟踪关联起来

示例是聚合数据的示例数据点。它们为一般的聚合提供了特定的上下文。一个常见的用例是能够将指标与(和日志)跟踪相关联。

本指南演示了如何使用 OpenTelemetry .NET 中的示例,通过 Prometheus、Jaeger 和 Grafana 连接指标和跟踪。

什么是示例?

示例代表构成聚合指标的单个测量值。它们允许您

  • 将指标链接到测量值产生时处于活动状态的跟踪
  • 识别聚合指标中的异常值或有趣的数据点
  • 通过查看相关的跟踪更好地理解指标变化的原因

本指南中使用的组件

  • OpenTelemetry .NET SDK:应用程序的仪表化
  • Prometheus:支持示例的指标后端
  • Jaeger:分布式跟踪后端
  • Grafana:用于查询指标和跟踪,并通过示例在它们之间导航的用户界面

设置

安装和运行 Jaeger

  1. 下载 Jaeger 的最新二进制分发版
  2. 将其解压到本地目录
  3. 运行 jaeger-all-in-one(.exe) 可执行文件
./jaeger-all-in-one --collector.otlp.enabled

安装和运行 Prometheus

  1. 下载 Prometheus 的最新版本
  2. 将其解压到本地目录
  3. 运行 Prometheus 并带上必需的功能标志
./prometheus --enable-feature=exemplar-storage --web.enable-otlp-receiver

安装和配置 Grafana

  1. 按照特定于操作系统的说明安装 Grafana
  2. 启动 Grafana 服务器
  3. 在浏览器中打开 https://:3000/
  4. 使用默认凭据 (admin/admin) 登录
  5. 配置数据源

Jaeger 数据源

  1. 导航到 配置 > 数据源
  2. 添加一个 Jaeger 数据源
  3. 将“URL”设置为 https://:16686/
  4. 点击“保存并测试”

Prometheus 数据源

  1. 导航到 配置 > 数据源
  2. 添加一个 Prometheus 数据源
  3. 将“URL”设置为 https://:9090
  4. 在“示例”下,启用“内部链接”
  5. 将“数据源”设置为 Jaeger,将“标签名称”设置为 trace_id
  6. 点击“保存并测试”

仪表化你的应用程序

这是一个关于如何使用 OpenTelemetry 仪表化 .NET 应用程序并启用示例的示例

using System;
using System.Diagnostics;
using System.Threading;
using OpenTelemetry;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;

// Create a resource with service information
var resource = ResourceBuilder.CreateDefault()
    .AddService(serviceName: "exemplars-demo", serviceVersion: "1.0.0");

// Create a tracer provider
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .SetResourceBuilder(resource)
    .AddSource("MyCompany.MyProduct.MyLibrary")
    .AddOtlpExporter(options => options.Endpoint = new Uri("https://:4317"))
    .Build();

// Create a meter provider with exemplar support
using var meterProvider = Sdk.CreateMeterProviderBuilder()
    .SetResourceBuilder(resource)
    .AddMeter("MyCompany.MyProduct.MyLibrary")
    .SetExemplarFilter(ExemplarFilterType.TraceBased)  // Enable trace-based exemplars
    .AddOtlpExporter(options => options.Endpoint = new Uri("https://:9090/api/v1/otlp"))
    .Build();

// Create activity source and meter
var activitySource = new ActivitySource("MyCompany.MyProduct.MyLibrary");
var meter = new Meter("MyCompany.MyProduct.MyLibrary");

// Create a histogram instrument for recording measurements
var histogram = meter.CreateHistogram<double>("MyHistogram", unit: "ms", description: "Example histogram");

var random = new Random();

// Generate sample data
for (int i = 0; i < 100; i++)
{
    // Start an activity (span)
    using (var activity = activitySource.StartActivity("ProcessData"))
    {
        // Add some attributes to the activity
        activity?.SetTag("iteration", i);

        // Simulate work
        var value = random.NextDouble() * 100;
        Thread.Sleep((int)value);

        // Record a measurement - this will include exemplar with trace context
        // because we set ExemplarFilterType.TraceBased and have an active activity
        histogram.Record(value);
    }

    // Sleep between iterations
    Thread.Sleep(100);
}

Console.WriteLine("Application running and sending data. Press any key to exit.");
Console.ReadKey();

在 Grafana 中查看示例

  1. 打开 Grafana 并导航到“探索”
  2. 选择 Prometheus 作为数据源
  3. 查询 MyHistogram_bucket 指标
  4. 切换“示例”选项并刷新查询

示例将显示为指标图表上的菱形点。点击示例时,您将看到详细信息,包括

  • 记录测量值的时间戳
  • 原始值
  • 跟踪上下文 (trace_id)

您可以点击 trace_id 旁边的“用 Jaeger 查询”来查看关联的跟踪,从而深入了解在记录特定测量值时发生了什么。

示例在 OpenTelemetry .NET 中如何工作

当您使用 SetExemplarFilter(ExemplarFilterType.TraceBased) 配置 SDK 时,SDK 会将跟踪信息(trace ID、span ID)附加到在活动 span 上下文中发生的度量测量值。这使得指标后端可以存储这些示例并将它们链接回相应的跟踪。

默认情况下,并非所有测量值都会存储为示例(这会效率低下)。后端通常使用采样策略来决定存储哪些测量值作为示例。

了解更多