使用示例
了解如何使用示例将指标与 OpenTelemetry .NET 中的跟踪关联起来
示例是聚合数据的示例数据点。它们为一般的聚合提供了特定的上下文。一个常见的用例是能够将指标与(和日志)跟踪相关联。
本指南演示了如何使用 OpenTelemetry .NET 中的示例,通过 Prometheus、Jaeger 和 Grafana 连接指标和跟踪。
什么是示例?
示例代表构成聚合指标的单个测量值。它们允许您
- 将指标链接到测量值产生时处于活动状态的跟踪
- 识别聚合指标中的异常值或有趣的数据点
- 通过查看相关的跟踪更好地理解指标变化的原因
本指南中使用的组件
- OpenTelemetry .NET SDK:应用程序的仪表化
- Prometheus:支持示例的指标后端
- Jaeger:分布式跟踪后端
- Grafana:用于查询指标和跟踪,并通过示例在它们之间导航的用户界面
设置
安装和运行 Jaeger
- 下载 Jaeger 的最新二进制分发版
- 将其解压到本地目录
- 运行
jaeger-all-in-one(.exe)可执行文件
./jaeger-all-in-one --collector.otlp.enabled
安装和运行 Prometheus
- 下载 Prometheus 的最新版本
- 将其解压到本地目录
- 运行 Prometheus 并带上必需的功能标志
./prometheus --enable-feature=exemplar-storage --web.enable-otlp-receiver
安装和配置 Grafana
- 按照特定于操作系统的说明安装 Grafana
- 启动 Grafana 服务器
- 在浏览器中打开 https://:3000/
- 使用默认凭据 (admin/admin) 登录
- 配置数据源
Jaeger 数据源
- 导航到 配置 > 数据源
- 添加一个 Jaeger 数据源
- 将“URL”设置为
https://:16686/ - 点击“保存并测试”
Prometheus 数据源
- 导航到 配置 > 数据源
- 添加一个 Prometheus 数据源
- 将“URL”设置为
https://:9090 - 在“示例”下,启用“内部链接”
- 将“数据源”设置为
Jaeger,将“标签名称”设置为trace_id - 点击“保存并测试”
仪表化你的应用程序
这是一个关于如何使用 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 中查看示例
- 打开 Grafana 并导航到“探索”
- 选择 Prometheus 作为数据源
- 查询
MyHistogram_bucket指标 - 切换“示例”选项并刷新查询
示例将显示为指标图表上的菱形点。点击示例时,您将看到详细信息,包括
- 记录测量值的时间戳
- 原始值
- 跟踪上下文 (trace_id)
您可以点击 trace_id 旁边的“用 Jaeger 查询”来查看关联的跟踪,从而深入了解在记录特定测量值时发生了什么。
示例在 OpenTelemetry .NET 中如何工作
当您使用 SetExemplarFilter(ExemplarFilterType.TraceBased) 配置 SDK 时,SDK 会将跟踪信息(trace ID、span ID)附加到在活动 span 上下文中发生的度量测量值。这使得指标后端可以存储这些示例并将它们链接回相应的跟踪。
默认情况下,并非所有测量值都会存储为示例(这会效率低下)。后端通常使用采样策略来决定存储哪些测量值作为示例。