System.Diagnostics.Metrics .NET 6 全新指标API讲解
前言
工友们, .net 6 preview 7 已经在8月10号发布了, 除了众多的功能更新和性能改进之外, 在 preview 7 版本中, 也新增了全新的指标api, system.diagnostics.metrics, 为了让应用能有更好的可观测性, 在之前的发布的.net 5中, 也把 activity 增强为 activitysource, 主要原因还是 .net 运行时团队和 opentelemetry .net sig 进行了深度合作, 并且一起制定了 opentelemetry .net 指标计划。
目前 system.diagnostics.metrics 这个api还只能在 .net preview 7 中使用, 当然后边也会像 system.text.json库一样发布到nuget平台, 让其他版本的 .net 项目接入使用。
指标介绍
下边介绍了几个主要的类
- meter 用来创建和跟踪指标instrument
- meterlistener 用来监听指标instrument的值的更新
- counter 计数器, 一般记录累加的值, 比如程序中的错误数, 请求数 都可以用计数器
- histogram 直方图, 记录可统计的值, 比如记录下每一个接口的响应时间, 然后再根据时间进行汇总
- observablecounter 可观察计数器, 一般记录累加的值, 比如 cpu 时间等
- observablegauge 可观测仪表盘, 你可以用来记录应用的内存, gc 的内存等
meter
meter类用来创建各种指标instrument, 包括计数器,直方图,仪表盘指标等等, meter 类包含了 name 和 version 属性, 你可以设置meter的名称和版本。
var meter = new meter("meter","v1.0"); var requestcount = meter.createcounter<long>("requestcount"); var responsetime = meter.createhistogram<long>("responsetime"); // ...
meterlistener
meterlistener 可以用来监听指标组件的值变化, 同样相对应的也有 activitylistener。
meterlistener listener = new meterlistener(); listener.instrumentpublished = (instrument, meterlistener) => { console.writeline($"enablemeasurementevents {instrument.name} "); meterlistener.enablemeasurementevents(instrument); }; listener.setmeasurementeventcallback<long>((instrument, measurement, tags, state) => { console.writeline($"instrument: {instrument.name} has recorded the measurement {measurement}"); }); listener.measurementscompleted = (instrument, state) => { listener.disablemeasurementevents(instrument); }; listener.start();
属性
- instrumentpublished 当使用meter类创建指标instrument时, 这个回调可以接收到创建的指标信息。
- measurementscompleted 当停止指标的收集时,这个回调可以接收到相应的指标信息, 通常是执行了 meter 和 meterlistener 的dispose() 方法
方法
- enablemeasurementevents 开启相应指标instrument的监听
- disablemeasurementevents 关闭相应指标instrument的监听
- setmeasurementeventcallback 设置指标instrument的测量值更新的回调
- recordobservableinstruments 记录所有监听的可观察指标(observable instruments)的当前测量值。
- start 开启监听指标instrument。
counter 计数器
counter是计数器指标,可以用来记录累加的值,使用非常简单,下边的示例中,模拟记录了程序的请求次数,首先调用 createcounter 函数创建一个计数器指标 requestcount, 然后调用add 方法, 进行counter的累加操作。
meter meter = new meter("meter","v1.0"); var requestcount = meter.createcounter<long>("requestcount"); for (int i = 0; i < 10; i++) { requestcount.add(1); }
然后使用上面的 meterlistener 来监听计数器指标, 程序的输出如下:
在第一行, meterlistener 检测到了上面创建的 requestcount 计数器, 并且开启了指标的监听, 当我们调用 requestcount.add(1) 后, meterlistener 捕获到了指标测量值的更新, 然后在控制台输出了相应的值, 需要注意的是, measurementeventcallback 回调方法只会捕获指标每次更新的测量值, 而不是汇总后的总数,所以这里的输出都是1。
histogram 直方图
histogram 是直方图指标,记录可统计的值, 比如记录下每一个接口的响应时间, 然后再根据时间进行汇总, 和 counter 差不多, 不过指标的维度不一样, 而且 histogram 使用record()方法记录每次的值,而不是add()方法。
meter meter = new meter("meter","v1.0"); var responsetime = meter.createhistogram<long>("responsetime"); for (int i = 0; i < 10; i++) { var cost = new random().next(100,1000); responsetime.record(cost); }
用随机数表示了接口的响应耗时, 输出如下:
observablecounter 可观察计数器
observablecounter 是可观察的计数器, 和 counter 不一样的是, 创建 observablecounter 需要传入一个func委托, 来返回一个测量值, 当然也不需要手动调用 add(), record() 方法, 只需要定时调用 meterlistener的recordobservableinstruments 方法, 获取当前的指标测量值。
class program { static async task main(string[] args) { meterlistener listener = new meterlistener(); start(listener); autorecord(listener); meter meter = new meter("meter","v1.0"); _ = meter.createobservablecounter<long>("cpu_counter",() => new random().next(100,1000)); console.readkey(); } static void start(meterlistener listener) { listener.instrumentpublished = (instrument, meterlistener) => { console.writeline($"enablemeasurementevents {instrument.name} "); meterlistener.enablemeasurementevents(instrument); }; listener.setmeasurementeventcallback<long>((instrument, measurement, tags, state) => { console.writeline($"instrument: {instrument.name} has recorded the measurement {measurement}"); }); listener.measurementscompleted = (instrument, state) => { listener.disablemeasurementevents(instrument); }; listener.start(); } static void autorecord(meterlistener listener) { var cts = new cancellationtokensource(); _ = task.run(async () => { while (!cts.iscancellationrequested) { await task.delay(3000); listener.recordobservableinstruments(); } }); } }
observablegauge 仪表盘指标
这个比较好理解, 你可以用来记录应用的内存,gc 的内存等, 同样是可观察指标, 也需要传入一个返回测量值的func委托。
meterlistener listener = new meterlistener(); start(listener); autorecord(listener); meter meter = new meter("meter","v1.0"); _ = meter.createobservablegauge<long>("gc_memory_gauge",() => gc.gettotalmemory(false)); console.readkey();
程序的输出如下:
总结
本文主要介绍了.net 6 指标api system.diagnostics.metrics,通过这些api, 可以很方便的收集应用的指标数据, 但是本文好像没有提到数据的聚合汇总? 不要担心, 运行时团队针对相应的指标api已经开发了一系列高性能的聚合api, 预计在.net 6 preview 8 中发布更新!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 部署.NET6项目到IIS