Vlastní kolekce metrik v .NET a .NET Core

Sady AZURE Monitor Application Přehledy .NET a .NET Core SDK mají dvě různé metody shromažďování vlastních metrik: TrackMetric() a GetMetric(). Klíčovým rozdílem mezi těmito dvěma metodami je místní agregace. Metoda TrackMetric() nemá před agregaci. Metoda GetMetric() má před agregaci. Doporučujeme použít agregaci, takže TrackMetric() už není upřednostňovanou metodou shromažďování vlastních metrik. Tento článek vás provede použitím GetMetric() metody a některých důvodů, jak funguje.

Poznámka:

Následující dokumentace se spoléhá na rozhraní API Přehledy Application Přehledy Classic. Dlouhodobým plánem pro application Přehledy je shromažďovat data pomocí OpenTelemetry. Další informace najdete v tématu Povolení OpenTelemetry služby Azure Monitor pro aplikace .NET, Node.js, Python a Java.

Agregace a agregace rozhraní API bez předběžné agregace

Metoda TrackMetric() odesílá nezpracovanou telemetrii označující metriku. Odeslání jedné položky telemetrie pro každou hodnotu je neefektivní. Metoda TrackMetric() je také neefektivní z hlediska výkonu, protože každá TrackMetric(item) prochází celým kanálem sady SDK inicializátorů telemetrie a procesorů.

Na rozdíl od TrackMetric(), GetMetric() zpracovává místní předběžné agregace za vás a pak odešle agregovanou souhrnnou metriku pouze v pevném intervalu jedné minuty. Pokud potřebujete pečlivě monitorovat určitou vlastní metriku na druhé nebo dokonce milisekundové úrovni, můžete to udělat, zatímco náklady na úložiště a síťový provoz se budou monitorovat jenom každou minutu. Toto chování také výrazně snižuje riziko omezování, protože celkový počet položek telemetrie, které je potřeba odeslat pro agregovanou metriku, se výrazně sníží.

V Přehledy aplikace vlastní metriky shromážděné prostřednictvím TrackMetric() vzorkování a GetMetric() nejsou předmětem vzorkování. Vzorkování důležitých metrik může vést ke scénářům, ve kterých by mohlo dojít k nespolehlivému upozorňování na tyto metriky. Díky tomu, že nikdy neodejdete vlastní metriky, můžete mít obecně jistotu, že když dojde k porušení prahových hodnot upozornění, aktivuje se upozornění. Vzhledem k tomu, že vlastní metriky nejsou vzorkovány, existuje několik potenciálních obav.

Sledování trendu v metrikách každou sekundu nebo v ještě podrobnějším intervalu může vést k:

  • Zvýšení nákladů na úložiště dat Náklady jsou spojené s objemem dat, která odesíláte do služby Azure Monitor. Čím více dat odesíláte, tím větší jsou celkové náklady na monitorování.
  • Zvýšení síťového provozu nebo režijního výkonu V některých scénářích by tato režie mohla mít peněžní i aplikační náklady na výkon.
  • Riziko omezování příjmu dat Když vaše aplikace během krátkého časového intervalu odesílá vysokou míru telemetrie, azure Monitor zahodí datové body ("omezení").

Omezování je problém, protože může vést k zmeškaným výstrahám. Podmínka, která aktivuje výstrahu, může nastat místně a pak se v koncovém bodu příjmu dat zahodí kvůli příliš velkému množství dat. Nedoporučujeme používat TrackMetric() pro .NET a .NET Core, pokud jste neimplementovali vlastní místní agregační logiku. Pokud se pokoušíte sledovat každou instanci, ke které dojde v daném časovém období, můžete zjistit, že TrackEvent() je to vhodnější. Mějte na paměti, že na rozdíl od vlastních metrik podléhají vlastní události vzorkování. Stále můžete používat TrackMetric() i bez psaní vlastní místní předběžné agregace. Ale pokud to uděláte, mějte na paměti úskalí.

V souhrnu doporučujeme GetMetric() , protože provádí předběžnou agregaci, shromažďuje hodnoty ze všech Track() volání a odesílá souhrn/agregaci jednou za minutu. Metoda GetMetric() může výrazně snížit náklady a režijní náklady tím, že odesílá méně datových bodů a přitom shromažďuje všechny relevantní informace.

Poznámka:

Pouze sady .NET a .NET Core SDK mají metodu GetMetric() . Pokud používáte Javu, přečtěte si téma Odesílání vlastních metrik pomocí mikrometru. Pro JavaScript a Node.js byste stále používali TrackMetric(), ale mějte na paměti upozornění, které byly popsány v předchozí části. V Pythonu můžete k odesílání vlastních metrik použít OpenCensus.stats , ale implementace metrik se liší.

Začínáme s GetMetric

V našich příkladech použijeme základní aplikaci pracovních služeb .NET Core 3.1. Pokud chcete replikovat testovací prostředí použité s těmito příklady, postupujte podle kroků 1 až 6 v článku o monitorovací pracovní službě. Tento postup přidá Přehledy aplikace do šablony projektu služby pracovního procesu. Tyto koncepty platí pro jakoukoli obecnou aplikaci, ve které je možné sadu SDK použít, včetně webových aplikací a konzolových aplikací.

Odesílání metrik

Obsah souboru worker.cs nahraďte následujícím kódem:

using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.ApplicationInsights;

namespace WorkerService3
{
    public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;
        private TelemetryClient _telemetryClient;

        public Worker(ILogger<Worker> logger, TelemetryClient tc)
        {
            _logger = logger;
            _telemetryClient = tc;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {   // The following line demonstrates usages of GetMetric API.
            // Here "computersSold", a custom metric name, is being tracked with a value of 42 every second.
            while (!stoppingToken.IsCancellationRequested)
            {
                _telemetryClient.GetMetric("ComputersSold").TrackValue(42);

                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(1000, stoppingToken);
            }
        }
    }
}

Při spuštění ukázkového kódu se smyčka while opakovaně spouští bez odesílání telemetrie v okně výstupu sady Visual Studio. Jedna položka telemetrie se odesílá kolem 60sekundové značky, která v našem testu vypadá takto:

Application Insights Telemetry: {"name":"Microsoft.ApplicationInsights.Dev.00000000-0000-0000-0000-000000000000.Metric", "time":"2019-12-28T00:54:19.0000000Z",
"ikey":"00000000-0000-0000-0000-000000000000",
"tags":{"ai.application.ver":"1.0.0.0",
"ai.cloud.roleInstance":"Test-Computer-Name",
"ai.internal.sdkVersion":"m-agg2c:2.12.0-21496",
"ai.internal.nodeName":"Test-Computer-Name"},
"data":{"baseType":"MetricData",
"baseData":{"ver":2,"metrics":[{"name":"ComputersSold",
"kind":"Aggregation",
"value":1722,
"count":41,
"min":42,
"max":42,
"stdDev":0}],
"properties":{"_MS.AggregationIntervalMs":"42000",
"DeveloperMode":"true"}}}}

Tato jedna položka telemetrie představuje agregaci 41 různých měření metrik. Vzhledem k tomu, že jsme odeslali stejnou hodnotu znovu a znovu, máme směrodatnou odchylku (stDev) 0 s identickými maximálními (max) a minimálními (min) hodnotami. Vlastnost value představuje součet všech jednotlivých hodnot, které byly agregovány.

Poznámka:

Metoda GetMetric nepodporuje sledování poslední hodnoty (například gauge) nebo sledování histogramů nebo distribucí.

Pokud prozkoumáme náš prostředek Přehledy aplikace v prostředí Protokolů (Analytics), jednotlivé položky telemetrie by vypadaly jako na následujícím snímku obrazovky.

Screenshot that shows the Log Analytics query view.

Poznámka:

I když nezpracovaná položka telemetrie po ingestování neobsahovala explicitní vlastnost součtu nebo pole, vytvoříme ji pro vás. V tomto případě obě vlastnosti valuevalueSum představují stejnou věc.

Ke své vlastní telemetrii metrik můžete přistupovat také v části Metriky na portálu jako na základě protokolů i k vlastní metrice. Následující snímek obrazovky je příkladem metriky založené na protokolu.

Screenshot that shows the Metrics explorer view.

Referenční informace o metrikách mezipaměti pro využití s vysokou propustností

Hodnoty metrik můžou být v některých případech často pozorovány. Například služba s vysokou propustností, která zpracovává 500 požadavků za sekundu, může pro každý požadavek generovat 20 metrik telemetrie. Výsledek znamená sledování 10 000 hodnot za sekundu. V takových scénářích s vysokou propustností můžou uživatelé potřebovat pomoct sadě SDK tím, že se vyhnete některým vyhledáváním.

Například předchozí příklad provedl vyhledávání popisovače metriky ComputersSold a pak sledoval pozorovanou hodnotu 42. Místo toho může být popisovač uložen v mezipaměti pro více volání sledování:

//...

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            // This is where the cache is stored to handle faster lookup
            Metric computersSold = _telemetryClient.GetMetric("ComputersSold");
            while (!stoppingToken.IsCancellationRequested)
            {

                computersSold.TrackValue(42);

                computersSold.TrackValue(142);

                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(50, stoppingToken);
            }
        }

Kromě ukládání popisovače metriky do mezipaměti se předchozí příklad snížil Task.Delay také na 50 milisekund, aby se smyčka spustila častěji. Výsledkem je 772 TrackValue() vyvolání.

Multidimenzionální metriky

Příklady v předchozí části zobrazují nulové metriky. Metriky navíc můžou být multidimenzionální. V současné době podporujeme až 10 dimenzí.

Tady je příklad vytvoření jednorozměrné metriky:

//...

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            // This is an example of a metric with a single dimension.
            // FormFactor is the name of the dimension.
            Metric computersSold= _telemetryClient.GetMetric("ComputersSold", "FormFactor");

            while (!stoppingToken.IsCancellationRequested)
            {
                // The number of arguments (dimension values)
                // must match the number of dimensions specified while GetMetric.
                // Laptop, Tablet, etc are values for the dimension "FormFactor"
                computersSold.TrackValue(42, "Laptop");
                computersSold.TrackValue(20, "Tablet");
                computersSold.TrackValue(126, "Desktop");


                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(50, stoppingToken);
            }
        }

Spuštění ukázkového kódu po dobu nejméně 60 sekund způsobí, že se do Azure odesílají tři různé položky telemetrie. Každá položka představuje agregaci jednoho ze tří faktorů formuláře. Stejně jako předtím můžete v zobrazení Protokolů (Analytics) podrobněji prozkoumat.

Screenshot that shows the Log Analytics view of multidimensional metric.

V Průzkumníku metrik:

Screenshot that shows Custom metrics.

Všimněte si, že metriku nemůžete rozdělit podle nové vlastní dimenze nebo zobrazit vlastní dimenzi pomocí zobrazení metrik.

Screenshot that shows splitting support.

Ve výchozím nastavení nejsou multidimenzionální metriky v Průzkumníku metrik v Přehledy prostředcích aplikace zapnuté.

Povolení multidimenzionálních metrik

Pokud chcete povolit multidimenzionální metriky pro prostředek Přehledy aplikace, vyberte Využití a odhadované náklady>– Vlastní metriky>Umožňují upozorňovat na vlastní dimenze>metrik OK. Další informace najdete v tématu Vlastní dimenze metrik a předběžné agregace.

Po provedení této změny a odeslání nové multidimenzionální telemetrie můžete vybrat Použít rozdělení.

Poznámka:

Pouze nově odeslané metriky po zapnutí funkce na portálu budou mít uložené dimenze.

Screenshot that shows applying splitting.

Zobrazte agregace metrik pro každou FormFactor dimenzi.

Screenshot that shows form factors.

Použití MetricIdentifier, pokud je více než tři dimenze

V současné době se podporuje 10 dimenzí. Použití více než tří dimenzí vyžaduje:MetricIdentifier

// Add "using Microsoft.ApplicationInsights.Metrics;" to use MetricIdentifier
// MetricIdentifier id = new MetricIdentifier("[metricNamespace]","[metricId],"[dim1]","[dim2]","[dim3]","[dim4]","[dim5]");
MetricIdentifier id = new MetricIdentifier("CustomMetricNamespace","ComputerSold", "FormFactor", "GraphicsCard", "MemorySpeed", "BatteryCapacity", "StorageCapacity");
Metric computersSold  = _telemetryClient.GetMetric(id);
computersSold.TrackValue(110,"Laptop", "Nvidia", "DDR4", "39Wh", "1TB");

Vlastní konfigurace metriky

Pokud chcete změnit konfiguraci metriky, musíte provést změny v místě, kde je metrika inicializována.

Speciální názvy dimenzí

Metriky nepoužívají kontext telemetrie použitého TelemetryClient pro přístup k nim. Použití speciálních názvů dimenzí dostupných jako konstant ve MetricDimensionNames třídě je nejlepším alternativním řešením pro toto omezení.

Agregace metrik odesílané pomocí následující Special Operation Request Size metriky nebudou nastaveny Context.Operation.Name na Special Operationhodnotu . Metoda TrackMetric() nebo jakákoli jiná TrackXXX() metoda bude OperationName správně nastavena na Special Operation.

        //...
        TelemetryClient specialClient;
        private static int GetCurrentRequestSize()
        {
            // Do stuff
            return 1100;
        }
        int requestSize = GetCurrentRequestSize()

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                //...
                specialClient.Context.Operation.Name = "Special Operation";
                specialClient.GetMetric("Special Operation Request Size").TrackValue(requestSize);
                //...
            }
                   
        }

V tomto případě použijte speciální názvy dimenzí uvedené ve MetricDimensionNames třídě k určení TelemetryContext hodnot.

Pokud se například agregace metriky vyplývající z dalšího příkazu odešle do koncového bodu cloudu Přehledy aplikace, nastaví se jeho Context.Operation.Name datové pole naSpecial Operation:

_telemetryClient.GetMetric("Request Size", MetricDimensionNames.TelemetryContext.Operation.Name).TrackValue(requestSize, "Special Operation");

Hodnoty této zvláštní dimenze se zkopírují a TelemetryContext nebudou použity jako normální dimenze. Pokud chcete zachovat také dimenzi operace pro normální zkoumání metrik, musíte pro tento účel vytvořit samostatnou dimenzi:

_telemetryClient.GetMetric("Request Size", "Operation Name", MetricDimensionNames.TelemetryContext.Operation.Name).TrackValue(requestSize, "Special Operation", "Special Operation");

Omezení dimenzí a časových řad

Pokud chcete zabránit náhodnému používání telemetrického subsystému, můžete řídit maximální počet datových řad na metriku. Výchozí limity nejsou větší než 1 000 celkových datových řad na metriku a ne více než 100 různých hodnot na dimenzi.

Důležité

Pro dimenze používejte nízké hodnoty kardinality, abyste se vyhnuli omezování.

V kontextu omezování dimenzí a časových řad používáme Metric.TrackValue(..) k zajištění toho, aby se limity sledovaly. Pokud už jsou limity dosaženy, Metric.TrackValue(..) vrátí False se a hodnota se nesleduje. V opačném případě se vrátí True. Toto chování je užitečné, pokud data metriky pocházejí ze vstupu uživatele.

Konstruktor MetricConfiguration má několik možností, jak spravovat různé řady v rámci příslušné metriky a objekt třídy implementuje IMetricSeriesConfiguration , který určuje chování agregace pro jednotlivé řady metriky:

var metConfig = new MetricConfiguration(seriesCountLimit: 100, valuesPerDimensionLimit:2,
                new MetricSeriesConfigurationForMeasurement(restrictToUInt32Values: false));

Metric computersSold = _telemetryClient.GetMetric("ComputersSold", "Dimension1", "Dimension2", metConfig);

// Start tracking.
computersSold.TrackValue(100, "Dim1Value1", "Dim2Value1");
computersSold.TrackValue(100, "Dim1Value1", "Dim2Value2");

// The following call gives 3rd unique value for dimension2, which is above the limit of 2.
computersSold.TrackValue(100, "Dim1Value1", "Dim2Value3");
// The above call does not track the metric, and returns false.
  • seriesCountLimit je maximální počet datových časových řad, které může metrika obsahovat. Když dosáhnete tohoto limitu, volání TrackValue() , která by normálně způsobovala vrácení falsenové řady .
  • valuesPerDimensionLimit omezuje počet jedinečných hodnot na dimenzi podobným způsobem.
  • restrictToUInt32Values určuje, zda mají být sledovány pouze nezáporné celočíselné hodnoty.

Tady je příklad, jak odeslat zprávu s informacemi o překročení limitů limitu:

if (! computersSold.TrackValue(100, "Dim1Value1", "Dim2Value3"))
{
// Add "using Microsoft.ApplicationInsights.DataContract;" to use SeverityLevel.Error
_telemetryClient.TrackTrace("Metric value not tracked as value of one of the dimension exceeded the cap. Revisit the dimensions to ensure they are within the limits",
SeverityLevel.Error);
}

Další kroky