在.NET中使用OpenTelemetry实现性能监控
.Net是用什么来收集指标数据的?
使用Meter类来产生数据
自.Net 6以后都是通过Meter这个类来实现的,System.Diagnostics.Metrics API 是最新的跨平台 API,是通过与 OpenTelemetry 项目的密切合作设计的。下面是这个Meter提供的指标与OpenTelemetry的指标的一个对应表格:
OpenTelemetry Specification .NET Instrument Type Asynchronous Counter ObservableCounter
Asynchronous Gauge ObservableGauge
Asynchronous UpDownCounter ObservableUpDownCounter
Counter Counter
Gauge Gauge
Histogram Histogram
UpDownCounter UpDownCounter
然后使用MeterListener来接收数据。下面举个例子来解释如何使用Meter和MeterListener:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44using System.Diagnostics.Metrics;
class Program
{
static Meter s_meter = new("HatCo.HatStore", "1.0.0");
static Counter<int> s_hatsSold = s_meter.CreateCounter<int>(
name: "hats-sold",
unit: "Hats",
description: "The number of hats sold in our store");
static void Main(string[] args)
{
using MeterListener meterListener = new();
meterListener.InstrumentPublished = (instrument, listener) =>
{
if (instrument.Meter.Name is "HatCo.HatStore")
{
listener.EnableMeasurementEvents(instrument);
}
};
meterListener.SetMeasurementEventCallback<int>(OnMeasurementRecorded);
// Start the meterListener, enabling InstrumentPublished callbacks.
meterListener.Start();
var rand = Random.Shared;
Console.WriteLine("Press any key to exit");
while (!Console.KeyAvailable)
{
//// Simulate hat selling transactions.
Thread.Sleep(rand.Next(100, 2500));
s_hatsSold.Add(rand.Next(0, 1000));
}
}
static void OnMeasurementRecorded<T>(
Instrument instrument,
T measurement,
ReadOnlySpan<KeyValuePair<string, object?>> tags,
object? state)
{
Console.WriteLine($"{instrument.Name} recorded measurement {measurement}");
}
}以下输出显示了应用的输出,并针对每个度量值使用自定义回调:
1
2
3
4
5
6
7
8
9> dotnet run
Press any key to exit
hats-sold recorded measurement 978
hats-sold recorded measurement 775
hats-sold recorded measurement 666
hats-sold recorded measurement 66
hats-sold recorded measurement 914
hats-sold recorded measurement 912
...详细解释,请参看:收集指标 - .NET | Microsoft Learn。当然在OpenTelemetry中接收以后,当然不是简单的输出到控制台,而是通过Exporter发送到OpenTelemetry Collector或者特定的遥测数据服务器。监听的逻辑可以在这里找到:MeterProviderSdk
示例
前置条件:你已经按照这篇文章,搭建好了本地环境。
创建一个Asp.Net Core Web API项目,并且按照如下几个包:
- OpenTelemetry.Exporter.OpenTelemetryProtocol
- OpenTelemetry.Extensions.Hosting
- OpenTelemetry.Instrumentation.AspNetCore
在容器中注入必要的服务,大概类似这样:
1
2
3
4
5services.AddOpenTelemetry()
.ConfigureResource(b => b.AddService("OpenTelemetry.MetricsExample", serviceVersion: "1.0.0"))
.WithMetrics(builder => builder
.AddAspNetCoreInstrumentation()
.AddOtlpExporter());打开grafana,创建Dashboard,通过导入这2个ID:19925,19924。来查看指标数据,这2个ID可以在这里找到:Grafana Dotnet Team 最后你就可以得到如下的图表: