Megosztás a következőn keresztül:


Metrikák gyűjtése

Ez a cikk a következőre vonatkozik: ✔️ .NET Core 3.1 és újabb ✔️ .NET-keretrendszer 4.6.1 és újabb verziók

A rendszerezett kód képes numerikus mérések rögzítésére, de a méréseket általában összesíteni, továbbítani és tárolni kell, hogy hasznos metrikákat hozhasson létre a monitorozáshoz. Az adatok összesítésének, továbbításának és tárolásának folyamatát adatgyűjtésnek nevezzük. Ez az oktatóanyag több példát mutat be a metrikák gyűjtésére:

  • Metrikák feltöltése Grafana-ban OpenTelemetry és Prometheus használatával.
  • Metrikák valós idejű megtekintése dotnet-counters
  • Egyéni gyűjtési eszköz létrehozása a mögöttes .NET MeterListener API használatával.

Az egyéni metrikák rendszerezéséről és beállításairól további információt a metrika API-k összehasonlítása című témakörben talál.

Előfeltételek

Példaalkalmazás létrehozása

A metrikák összegyűjtése előtt méréseket kell létrehozni. Ez az oktatóanyag egy olyan alkalmazást hoz létre, amely alapszintű metrika-kialakítással rendelkezik. A .NET-futtatókörnyezet különböző beépített metrikákkal is rendelkezik. Az új metrikák API-val történő System.Diagnostics.Metrics.Meter létrehozásáról a rendszerállapot-oktatóanyagban talál további információt.

dotnet new console -o metric-instr
cd metric-instr
dotnet add package System.Diagnostics.DiagnosticSource

Cserélje le a következő kód tartalmát Program.cs :

using System.Diagnostics.Metrics;

class Program
{
    static Meter s_meter = new("HatCo.HatStore", "1.0.0");
    static Counter<int> s_hatsSold = s_meter.CreateCounter<int>("hats-sold");

    static void Main(string[] args)
    {
        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));
        }
    }
}

Az előző kód véletlenszerű időközönként és véletlenszerű időpontokban szimulálja a kalapok értékesítését.

Metrikák megtekintése dotnet-counters használatával

A dotnet-counters egy parancssori eszköz, amely igény szerint megtekintheti a .NET Core-alkalmazások élő metrikáit. Nincs szükség beállításra, így az ad-hoc vizsgálatokhoz vagy annak ellenőrzéséhez, hogy a metrika-rendszerállapot működik-e. Ez az api-k és az EventCounters használatával is System.Diagnostics.Metrics működik.

Ha a dotnet-counters eszköz nincs telepítve, futtassa a következő parancsot:

dotnet tool update -g dotnet-counters

Amíg a példaalkalmazás fut, indítsa el a dotnet-counters parancsokat. Az alábbi parancs egy példát mutat be a dotnet-counters mérőszám összes metrikájának HatCo.HatStore figyelésére. A mérő neve megkülönbözteti a kis- és nagybetűk nevét. A mintaalkalmazás a metric-instr.exe volt, ezt helyettesítse a mintaalkalmazás nevével.

dotnet-counters monitor -n metric-instr HatCo.HatStore

A következőhöz hasonló kimenet jelenik meg:

Press p to pause, r to resume, q to quit.
    Status: Running

[HatCo.HatStore]
    hats-sold (Count / 1 sec)                          4

dotnet-counters a .NET-futtatókörnyezet beépített rendszerállapotának megtekintéséhez különböző metrikákkal futtatható:

dotnet-counters monitor -n metric-instr

A következőhöz hasonló kimenet jelenik meg:

Press p to pause, r to resume, q to quit.
    Status: Running

[System.Runtime]
    % Time in GC since last GC (%)                                 0
    Allocation Rate (B / 1 sec)                                8,168
    CPU Usage (%)                                                  0
    Exception Count (Count / 1 sec)                                0
    GC Heap Size (MB)                                              2
    Gen 0 GC Count (Count / 1 sec)                                 0
    Gen 0 Size (B)                                         2,216,256
    Gen 1 GC Count (Count / 1 sec)                                 0
    Gen 1 Size (B)                                           423,392
    Gen 2 GC Count (Count / 1 sec)                                 0
    Gen 2 Size (B)                                           203,248
    LOH Size (B)                                             933,216
    Monitor Lock Contention Count (Count / 1 sec)                  0
    Number of Active Timers                                        1
    Number of Assemblies Loaded                                   39
    ThreadPool Completed Work Item Count (Count / 1 sec)           0
    ThreadPool Queue Length                                        0
    ThreadPool Thread Count                                        3
    Working Set (MB)                                              30

További információ: dotnet-counters. A .NET-beli metrikákkal kapcsolatos további információkért lásd a beépített metrikákat.

Metrikák megtekintése a Grafana-ban OpenTelemetry és Prometheus használatával

Áttekintés

OpenTelemetria:

  • A Cloud Native Computing Foundation által támogatott, szállítósemleges nyílt forráskódú projekt.
  • Szabványosítja a natív felhőbeli szoftverek telemetriájának generálását és gyűjtését.
  • A .NET-tel együttműködik a .NET metrika API-kkal.
  • Az Azure Monitor és számos APM-gyártó támogatja.

Ez az oktatóanyag az OSS Prometheus - és Grafana-projekteket használó OpenTelemetry-metrikákhoz elérhető integrációk egyikét mutatja be. A metrikák adatfolyama:

  1. A .NET metrika API-k rögzítik a méréseket a példaalkalmazásból.

  2. Az alkalmazásban futó OpenTelemetry-kódtár összesíti a méréseket.

  3. A Prometheus-exportőr kódtára elérhetővé teszi az összesített adatokat EGY HTTP-metrikák végponton keresztül. Az OpenTelemetria az "exportőr" azokat a kódtárakat hívja meg, amelyek telemetriát küldenek a szállítóspecifikus háttérrendszereknek.

  4. Prometheus-kiszolgáló:

    • A metrikák végpontjának lekérdezése
    • Beolvassa az adatokat
    • Az adatokat egy adatbázisban tárolja a hosszú távú megőrzése érdekében. A Prometheus arra utal, hogy az adatok olvasása és tárolása végpontok kaparásaként.
    • Futtatható egy másik gépen
  5. A Grafana-kiszolgáló:

    • Lekérdezi a Prometheusban tárolt adatokat, és megjeleníti azokat egy webes monitorozási irányítópulton.
    • Egy másik gépen is futtatható.

A példaalkalmazás konfigurálása az OpenTelemetry Prometheus-exportőrének használatára

Adjon hozzá egy hivatkozást az OpenTelemetry Prometheus-exportőrre a példaalkalmazáshoz:

dotnet add package OpenTelemetry.Exporter.Prometheus.HttpListener --prerelease

Megjegyzés:

Ez az oktatóanyag az OpenTelemetry Prometheus-támogatásának kiadás előtti buildjét használja, amely az írás időpontjában érhető el.

Frissítés Program.cs OpenTelemetria-konfigurációval:

using OpenTelemetry;
using OpenTelemetry.Metrics;
using 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 MeterProvider meterProvider = Sdk.CreateMeterProviderBuilder()
                .AddMeter("HatCo.HatStore")
                .AddPrometheusHttpListener(options => options.UriPrefixes = new string[] { "http://localhost:9184/" })
                .Build();

        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));
        }
    }
}

A fenti kód a következőket végzi el:

  • AddMeter("HatCo.HatStore") Az OpenTelemetry konfigurálja az alkalmazásban meghatározott mérőszám által gyűjtött összes metrikának továbbítására.
  • AddPrometheusHttpListener Az OpenTelemetria a következőre van konfigurálva:
    • Prometheus metrikavégpontjának elérhetővé helyezése a porton 9184
    • Használja a HttpListenert.

Az OpenTelemetry konfigurációs beállításairól további információt az OpenTelemetry dokumentációjában talál. Az OpenTelemetry dokumentációja ASP.NET alkalmazások üzemeltetési lehetőségeit mutatja be.

Futtassa az alkalmazást, és hagyja futni, hogy a mérések összegyűjthetők legyenek:

dotnet run

A Prometheus beállítása és konfigurálása

A Prometheus-kiszolgáló beállításához és működésének ellenőrzéséhez kövesse a Prometheus első lépéseit .

Módosítsa a prometheus.yml konfigurációs fájlt, hogy a Prometheus lekaparja a példaalkalmazás által feltárt metrikák végpontját. Adja hozzá a következő kiemelt szöveget a scrape_configs szakaszhoz:

# my global config
global:
  scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).

# Alertmanager configuration
alerting:
  alertmanagers:
    - static_configs:
        - targets:
          # - alertmanager:9093

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  # - "first_rules.yml"
  # - "second_rules.yml"

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: "prometheus"

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    static_configs:
      - targets: ["localhost:9090"]

  - job_name: 'OpenTelemetryTest'
    scrape_interval: 1s # poll very quickly for a more responsive demo
    static_configs:
      - targets: ['localhost:9184']

A Prometheus indítása

  1. Töltse be újra a konfigurációt, vagy indítsa újra a Prometheus-kiszolgálót.

  2. Győződjön meg arról, hogy az OpenTelemetryTest up állapotban van a Prometheus webportál Állapotcélok> lapján. Prometheus status

  3. A Prometheus webportál Gráf lapján írja be hats a kifejezés szövegmezőbe, és válassza hats_sold_Hatshat a Gráf lapon a Prometheus a példaalkalmazás által kibocsátott "kalapok-eladott" számláló növekvő értékét. Prometheus hats sold graph

Az előző képen a gráfidő 5 m-re van állítva, ami 5 perc.

Ha a Prometheus-kiszolgáló már régóta nem kaparja le a példaalkalmazást, előfordulhat, hogy várnia kell az adatok halmozódására.

Metrikák megjelenítése Grafana-irányítópulton

  1. A Grafana telepítéséhez és Prometheus-adatforráshoz való csatlakoztatásához kövesse a szokásos utasításokat .

  2. A Grafana-irányítópult létrehozásához kattintson a + bal oldali eszköztár ikonra a Grafana webportálon, majd válassza az Irányítópult lehetőséget. A megjelenő irányítópult-szerkesztőben írja be a Hat eladott/másodperc értéket a Cím beviteli mezőbe és a rate(hats_sold[5m]) kifejezést a PromQL kifejezésmezőbe:

    Hats sold Grafana dashboard editor

  3. Kattintson az Alkalmaz gombra az új irányítópult mentéséhez és megtekintéséhez.

    Hats sold Grafana dashboard]

Egyéni gyűjtési eszköz létrehozása a .NET MeterListener API használatával

A .NET MeterListener API lehetővé teszi egyéni folyamaton belüli logika létrehozását a rögzített mérések System.Diagnostics.Metrics.Metermegfigyeléséhez. A régebbi EventCounters-rendszerállapotokkal kompatibilis egyéni logika létrehozásával kapcsolatos útmutatásért tekintse meg az EventCounterst.

Módosítsa a használni MeterListenerkívánt kódjátProgram.cs:

using 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}");
    }
}

Az alábbi kimenet az alkalmazás kimenetét jeleníti meg egyéni visszahívással az egyes méréseken:

> 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
...

A mintakód ismertetése

Az ebben a szakaszban található kódrészletek az előző mintából származnak.

A következő kiemelt kódban a rendszer létrehoz egy példányt a MeterListener mérések fogadásához. A using kulcsszó akkor Dispose lesz meghívva, ha a meterListener hatókör kiesik.

using MeterListener meterListener = new();
meterListener.InstrumentPublished = (instrument, listener) =>
{
    if (instrument.Meter.Name is "HatCo.HatStore")
    {
        listener.EnableMeasurementEvents(instrument);
    }
};

Az alábbi kiemelt kód azt konfigurálja, hogy a figyelő mely eszközöktől fogad méréseket. InstrumentPublished egy olyan meghatalmazott, amelyet akkor hív meg a rendszer, ha új eszköz jön létre az alkalmazásban.

using MeterListener meterListener = new();
meterListener.InstrumentPublished = (instrument, listener) =>
{
    if (instrument.Meter.Name is "HatCo.HatStore")
    {
        listener.EnableMeasurementEvents(instrument);
    }
};

A meghatalmazott megvizsgálhatja az eszközt annak eldöntéséhez, hogy feliratkozik-e. A meghatalmazott például ellenőrizheti a nevet, a mérőt vagy bármely más nyilvános tulajdonságot. EnableMeasurementEvents lehetővé teszi a mérések fogadását a megadott műszerről. Olyan kód, amely egy másik megközelítéssel szerez be egy eszközre mutató hivatkozást:

  • Ez általában nem történik meg.
  • A hivatkozással bármikor meghívható EnableMeasurementEvents() .

Az a meghatalmazott, amelyet a rendszer meghív, amikor méréseket fogad egy eszközről, a következő hívással SetMeasurementEventCallbackvan konfigurálva:

    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}");
}

Az általános paraméter szabályozza, hogy a visszahívás milyen adattípusú mérést fogad. Például egy Counter<int> mérést generál int , Counter<double> méréseket hoz létre double . Az eszközök létrehozhatóak , short, int, long, float, doubleés decimal típusokkalbyte. Javasoljuk, hogy minden adattípushoz regisztráljon visszahívást, hacsak nem rendelkezik forgatókönyvspecifikus tudással arról, hogy nem minden adattípusra van szükség. A különböző általános argumentumokkal történő ismételt hívások SetMeasurementEventCallback kissé szokatlannak tűnhetnek. Az API-t úgy tervezték, hogy alacsony teljesítményű, általában csak néhány nanoszekundumos méréseket fogadhasson MeterListener .

Amikor MeterListener.EnableMeasurementEvents meghívják, egy state objektum megadható az egyik paraméterként. Az state objektum tetszőleges. Ha egy állapotobjektumot ad meg a hívásban, akkor a rendszer az adott eszközzel tárolja, és a visszahívás paramétereként state adja vissza. Ez mind kényelmi, mind teljesítményoptimalizálási célokat szolgál. A figyelőknek gyakran a következőkre van szükségük:

  • Hozzon létre egy objektumot minden olyan eszközhöz, amely méréseket tárol a memóriában.
  • A mérésekhez kóddal kell számításokat végeznie.

Másik lehetőségként hozzon létre egy Dictionary olyan eszközt, amely leképezi a műszert a tárolóobjektumra, és minden mérésen megkeresi. Dictionary A használata sokkal lassabb, mint a hozzáférés.state

meterListener.Start();

Az előző kód elindítja a MeterListener visszahívásokat engedélyező kódot. A InstrumentPublished rendszer meghívja a meghatalmazottat a folyamat minden meglévő eszközére. Az újonnan létrehozott eszközobjektumok is aktiválva InstrumentPublished lesznek.

using MeterListener meterListener = new MeterListener();

Ha az alkalmazás befejezte a figyeléseket, a figyelő letiltása leállítja a visszahívások folyamatát, és a figyelő objektumra mutató belső hivatkozásokat ad ki. A using változó hatókörének kiesésekor a deklaráláskor meterListener Dispose használt kulcsszó. Vegye figyelembe, hogy Dispose csak ígéretes, hogy nem kezdeményez új visszahívásokat. Mivel a visszahívások különböző szálakon fordulnak elő, előfordulhat, hogy a visszahívások a visszahívás Dispose után is folyamatban vannak.

Annak biztosítása érdekében, hogy a visszahívásban lévő kód egy bizonyos régiója jelenleg nem fut, és a jövőben nem fog futni, hozzá kell adni a szálszinkronizálást. Dispose alapértelmezés szerint nem tartalmazza a szinkronizálást, mert:

  • A szinkronizálás minden mérési visszahívásnál többletterhelést okoz.
  • MeterListener magas teljesítménytudatos API-ként lett kialakítva.