.Net中指标API应用

一、什么是指标

 指标是在一段时间内报告的数字度量值,主要用于监视应用程序的运行状况并生成警报。

 例如,Web 服务可能会跟踪每秒接收到的请求数、响应所花的毫秒数,以及向用户返回错误的响应数。 可以定期向监视系统报告这些指标。

 .NET 应用中使用指标涉及两个部分:

  • 检测: .NET 库中的代码采用度量值,并将这些度量值与指标名称关联起来
  • 采集:由一个 .NET 应用开发人员来配置需要传输应用中的哪些命名指标来进行外部存储和分析。 某些工具还使工程师能够利用配置文件或单独的 UI 在应用外部配置此功能。

二、.NET中指标API

 当前.NET中支持的指标API主要包含:PerformanceCounter(性能计数器)、EventCounters、System.Diagnostics.Metrics。

 主要区别如下:

.NET 指标 API
项目 PerformanceCounter EventCounters System.Diagnostics.Metrics
支持平台 Windows 支持跨平台(Windows/Linux)  支持跨平台(Windows/Linux)推荐使用
支持功能   支持报告更改率和平均值

EventCounters全部功能,以及新增功能

  • 直方图和百分位数
  • 多维指标
  • 强类型高性能侦听器 API
  • 多个同时使用的侦听器
  • 侦听器对未聚合度量值的访问
支持.NET版本 所有.NET 版本

.NET Core
部分.NET Framework 4.7.1 

.NET Framework 4.6.2
(安装System.Diagnostics.DiagnosticSource包)

  • EventCounters

   EventCounters 是 .NET API,用于轻量级、跨平台、准实时性能指标收集。 EventCounters 作为 Windows 上 .NET 框架的“性能计数器”的跨平台替代项添加。

   EventCounters 作为 EventSource 的一部分实时自动定期推送到侦听器工具。 与 EventSource 上所有其他事件一样,可以通过 EventListener 和 EventSource 在进程内和进程外使用它们。

 

   当前支持了两种类型EventCounters:

    • 用于计算比率的计数器:如调用频率(次/s)等;在.NET 中使用以下类型实现:
      • IncrementingEventCounter:记录每个时间间隔的运行总计。
      • IncrementingPollingCounter:使用回调来确定报告的增量值。 对于每个时间间隔,调用回调,然后当前调用与最后一个调用之间的差值是报告的值。
    • 用于返回当前值的计数器:如调用总次数等;在.NET 中使用以下类型实现:
      • EventCounter:记录一组值。 调用EventCounter.WriteMetric 方法将新值添加到集。 在每个间隔中,将计算集的统计摘要,如最小值、最大值和平均值。
      • PollingCounter:使用回调来确定报告的值。 在每个时间间隔中,调用用户提供的回调函数,然后返回值用作计数器值。 可以使用 PollingCounter 从外部源查询指标,例如获取磁盘上的当前可用字节。

   使用EventCounters 实现一组监控指标对这几个计数器类型更加理解:

   a)创建项目后,添加MinimalEventCounterSource 文件:用于计数器创建。计数器名称为:EventCounter.Minimal

[EventSource(Name = "EventCounter.Minimal")]
public sealed class MinimalEventCounterSource : EventSource
{
    public static readonly MinimalEventCounterSource Log = new MinimalEventCounterSource();

    //调用耗时:ms
    private EventCounter _requestCounter;

    //调用速率:调用次数/秒
    private IncrementingEventCounter _callCounter;

    PollingCounter _pollingCounter;

    IncrementingPollingCounter _incrementingPollingCounter;

    int callCount = 0;

    private MinimalEventCounterSource()
    {
        _requestCounter = new EventCounter("request-time", this)
        {
            DisplayName = "Request Processing Time",
            DisplayUnits = "ms"
        };
        //调用频率
        _callCounter = new IncrementingEventCounter("CallV", this) { DisplayName = "调用频率", DisplayUnits = "" };
        //调用次数(轮询)
        _pollingCounter = new PollingCounter("Call count", this, () => { return callCount; }) { DisplayName = "调用次数", DisplayUnits = "" };
        //调用频率(轮询)
        _incrementingPollingCounter = new IncrementingPollingCounter("CallVP", this, () => { return callCount; }) { DisplayName = "调用频率(P)", DisplayUnits = "" };
    }

    public void WriteMetric(string url, long elapsedMilliseconds)
    {
        WriteEvent(1, url, elapsedMilliseconds);
        _requestCounter?.WriteMetric(elapsedMilliseconds);
        _callCounter?.Increment(1);
        callCount++;
    }

    protected override void Dispose(bool disposing)
    {
        _requestCounter?.Dispose();
        _requestCounter = null;

        base.Dispose(disposing);
    }
}

   b)添加调用逻辑:

static void Main(string[] args)
{
    Console.WriteLine("Press any key to exit");
    Random random = new Random();
    while (!Console.KeyAvailable)
    {
        Thread.Sleep(100);
        MinimalEventCounterSource.Log.WriteMetric("test", random.Next(0, 100));
    }
    MinimalEventCounterSource.Log.Dispose();
}

   c)使用dotnet-counters查看指标:

//查看进程列表
>> dotnet-counters ps 22412 metric-instr F:\coding\DiagnosticsTools\metric-instr\bin\Debug\netcoreapp3.1\metric-instr.exe

//监控计数器EventCounter.Minimal
>> dotnet-counters monitor -p 22412 --counters EventCounter.Minimal

    

    监控指标成功读取,切实时更新.   

  • System.Diagnostics.Metrics:(推荐使用的API)

   支持指标类型:

    • 默认指标计算 - 收集和分析检测度量值的工具会根据不同的检测计算不同的默认指标。
    • 存储聚合数据 - 最有用的度量值需要通过多个度量值聚合数据。 一种选择是调用方在任意时间提供单独的度量值,再由集合工具管理聚合。 或者,调用方可以管理聚合度量值,并在回调中按需提供它们。

   当前实现的方式:

    • Counter () - 此检测在概念上跟踪随时间增加的值,并且调用方使用 Add 来报告增量。 大多数工具将计算总计数和总计数中的变化率。 对于仅显示一项内容的工具,建议显示变化率。

    • ObservableCounter () - 此检测类似于 Counter,只不过调用方现在负责维护聚合的总计数。 当创建 ObservableCounter 时,调用方会提供回调委托,并在每次工具需要观察当前总计数时调用回调。

    • ObservableGauge () - 此检测允许调用方提供一个回调,其中将度量值直接作为指标传递。 每次集合工具更新时,都会调用回调,并且回调返回的任何值都会显示在该工具中。

    • Histogram () - 此检测跟踪度量值的分布情况。 并没有单一的规范方法来描述一组测量,但建议使用直方图或计算百分比工具。

   a)类型示例:模拟业务数据指标变化。

using System;
using System.Diagnostics.Metrics;
using System.Threading;
class Program
{
    static Meter s_meter = new Meter("HatCo.HatStore", "1.0.0");
    static Counter<int> s_hatsSold = s_meter.CreateCounter<int>("hats-sold",unit: "Hats",description: "The number of hats sold in our store");
   static Histogram<int> s_orderProcessingTimeMs = s_meter.CreateHistogram<int>("order-processing-time");
   static int s_coatsSold;
    static int s_ordersPending;
    static Random s_rand = new Random();
    static void Main(string[] args)
    {
     //定时回调返回:外套数量 s_meter.CreateObservableCounter
<int>("coats-sold", () => s_coatsSold);
     //定时回调返回:待处理订单 s_meter.CreateObservableGauge
<int>("orders-pending", () => s_ordersPending); Console.WriteLine("Press any key to exit"); while(!Console.KeyAvailable) { Thread.Sleep(100); s_hatsSold.Add(4); s_coatsSold += 3; s_ordersPending = s_rand.Next(0, 20);
       //添加处理时间:订单处理时间 s_orderProcessingTimeMs.Record(s_rand.Next(5, 15)); } } }

    b)使用dotnet-counters查看指标

//查看进程列表
>> dotnet-counters ps
    22412 metric-instr F:\coding\DiagnosticsTools\metric-instr\bin\Debug\netcoreapp3.1\metric-instr.exe

//监控计数器EventCounter.Minimal
>> dotnet-counters monitor -p 22412 --counters EventCounter.Minimal

    c)度量值还可以与被称为标记的键值对相关联,从而能对数据进行分类以进行分析。

s_hatsSold.Add(2,
               new KeyValuePair<string, object>("Color", "Red"),
               new KeyValuePair<string, object>("Size", 12));

三、总结:

  可以在实际开发中,使用System.Diagnostics.Metrics添加些业务数据监控数据。

四、其他:

  .NET中的已知计数器

posted @ 2022-02-20 20:49  chaney1992  阅读(274)  评论(0编辑  收藏  举报