Kolekce vlastních metrik v rozhraní .NET a .NET CoreCustom metric collection in .NET and .NET Core

Sady SDK Azure Monitor Application Insights .NET a .NET Core mají dvě různé metody shromažďování vlastních metrik, TrackMetric() a GetMetric() .The Azure Monitor Application Insights .NET and .NET Core SDKs have two different methods of collecting custom metrics, TrackMetric(), and GetMetric(). Klíčový rozdíl mezi těmito dvěma metodami je místní agregace.The key difference between these two methods is local aggregation. TrackMetric()neobsahuje předagregaci, zatímco GetMetric() má předagregaci.TrackMetric() lacks pre-aggregation while GetMetric() has pre-aggregation. Doporučený postup je použít agregaci, proto už TrackMetric() není upřednostňovanou metodou shromažďování vlastních metrik.The recommended approach is to use aggregation, therefore, TrackMetric() is no longer the preferred method of collecting custom metrics. Tento článek vás provede použitím metody getmetric () a některých z odůvodnění, jak to funguje.This article will walk you through using the GetMetric() method, and some of the rationale behind how it works.

TrackMetric versus getmetricTrackMetric versus GetMetric

TrackMetric()odesílá nezpracované telemetrie, která označuje metriku.TrackMetric() sends raw telemetry denoting a metric. Je neefektivní odeslat jednu položku telemetrie pro každou hodnotu.It is inefficient to send a single telemetry item for each value. TrackMetric()je také neefektivní z pohledu výkonu, protože každý TrackMetric(item) projde kompletním kanálem sady SDK inicializátorů telemetrie a procesorů.TrackMetric() is also inefficient in terms of performance since every TrackMetric(item) goes through the full SDK pipeline of telemetry initializers and processors. Na rozdíl od TrackMetric() , GetMetric() zpracovává místní předagregaci za vás a poté odesílá agregovanou souhrnnou metriku v pevném intervalu 1 minuty.Unlike TrackMetric(), GetMetric() handles local pre-aggregation for you and then only submits an aggregated summary metric at a fixed interval of one minute. Takže pokud potřebujete úzce monitorovat určitou vlastní metriku na druhé nebo dokonce úrovni milisekund, můžete tak učinit, ale jenom náklady na úložiště a síťovou komunikaci jenom sledujete každou minutu.So if you need to closely monitor some custom metric at the second or even millisecond level you can do so while only incurring the storage and network traffic cost of only monitoring every minute. Tím se značně 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íží.This also greatly reduces the risk of throttling occurring since the total number of telemetry items that need to be sent for an aggregated metric are greatly reduced.

V Application Insights vlastní metriky shromažďované přes TrackMetric() a GetMetric() nepodléhají vzorkování.In Application Insights, custom metrics collected via TrackMetric() and GetMetric() are not subject to sampling. Vzorkování důležitých metrik může vést k situacím, kdy upozornění, která jste mohli vygenerovat kolem těchto metrik, by mohla být nespolehlivá.Sampling important metrics can lead to scenarios where alerting you may have built around those metrics could become unreliable. Když si vaše vlastní metriky nikdy nevzorkování, můžete si obecně být jistí, že když dojde k porušení prahových hodnot upozornění, aktivuje se výstraha.By never sampling your custom metrics, you can generally be confident that when your alert thresholds are breached, an alert will fire. Ale vzhledem k tomu, že vlastní metriky nejsou vzorkované, existují potenciální obavy.But since custom metrics aren't sampled, there are some potential concerns.

Pokud potřebujete sledovat trendy v metrikě každou sekundu, nebo v podrobnějším intervalu, může to mít za následek:If you need to track trends in a metric every second, or at an even more granular interval this can result in:

  • Zvýšené náklady na úložiště dat.Increased data storage costs. Existují náklady spojené s množstvím dat, která odesíláte do Azure Monitor.There is a cost associated with how much data you send to Azure Monitor. (Další data, která posíláte větší náklady na monitorování.)(The more data you send the greater the overall cost of monitoring.)
  • Zvýšení zátěže sítě/režie výkonu.Increased network traffic/performance overhead. (V některých případech to může mít náklady na výkon peněžních i aplikačních aplikací.)(In some scenarios this could have both a monetary and application performance cost.)
  • Riziko přijímání omezení příjmu.Risk of ingestion throttling. (Služba Azure Monitor vyřazuje datové body ("omezení"), když vaše aplikace pošle velmi vysokou míru telemetrie v krátkém časovém intervalu.)(The Azure Monitor service drops ("throttles") data points when your app sends a very high rate of telemetry in a short time interval.)

Omezování je obzvláště důležité v takovém případě, jako je vzorkování, omezování může vést k chybějícím výstrahám, protože podmínka pro aktivaci výstrahy může probíhat místně a pak se vynechá na koncovém bodu ingestování kvůli příliš velkému počtu odesílaných dat.Throttling is of particular concern in that like sampling, throttling can lead to missed alerts since the condition to trigger an alert could occur locally and then be dropped at the ingestion endpoint due to too much data being sent. To je důvod, proč rozhraní .NET a .NET Core nedoporučujeme používat, TrackMetric() Pokud jste neimplementovali vlastní místní logiku agregace.This is why for .NET and .NET Core we don't recommend using TrackMetric() unless you have implemented your own local aggregation logic. Pokud se snažíte sledovat každou instanci, ke které dojde v daném časovém období, může se stát, že TrackEvent() se to lépe hodí.If you are trying to track every instance an event occurs over a given time period, you may find that TrackEvent() is a better fit. I když mějte na paměti, že na rozdíl od vlastních metrik se vlastní události vztahují k odběru vzorků.Though keep in mind that unlike custom metrics, custom events are subject to sampling. Samozřejmě můžete kurz stále používat TrackMetric() i bez psaní vlastní místní předběžné agregace, ale pokud to uděláte, budete mít na nástrah vědět.You can of course still use TrackMetric() even without writing your own local pre-aggregation, but if you do so be aware of the pitfalls.

V souhrnu GetMetric() je doporučený přístup, protože se používá před agregací, shromažďuje hodnoty ze všech volání stop () a odesílá souhrn nebo agregaci jednou za minutu.In summary GetMetric() is the recommended approach since it does pre-aggregation, it accumulates values from all the Track() calls and sends a summary/aggregate once every minute. To může významně snížit náklady a režii na výkon tím, že posílá méně datových bodů a stále shromažďuje všechny relevantní informace.This can significantly reduce the cost and performance overhead by sending fewer data points, while still collecting all relevant information.

Poznámka

Pouze sady SDK .NET a .NET Core mají metodu getmetric ().Only the .NET and .NET Core SDKs have a GetMetric() method. Pokud používáte Java, můžete použít metriky mikroměřiče nebo TrackMetric() .If you are using Java you can use Micrometer metrics or TrackMetric(). V případě Pythonu můžete k posílání vlastních metrik používat OpenCensus. stat .For Python you can use OpenCensus.stats to send custom metrics. Pro JavaScript a Node.js, které byste pořád používali TrackMetric() , ale mějte na paměti upozornění, která byla popsaných v předchozí části.For JavaScript and Node.js you would still use TrackMetric(), but keep in mind the caveats that were outlined in the previous section.

Začínáme se službou getmetricGetting started with GetMetric

V našich příkladech budeme používat základní aplikaci pracovní služby pro .NET Core 3,1.For our examples, we are going to use a basic .NET Core 3.1 worker service application. Pokud chcete provést naprostou replikaci testovacího prostředí, které bylo použito s těmito příklady, postupujte podle kroků 1-6 článku o službě monitoring Worker a přidejte Application Insights do šablony projektu základní pracovní služby.If you would like to exactly replicate the test environment that was used with these examples, follow steps 1-6 of the monitoring worker service article to add Application Insights to a basic worker service project template. Tyto koncepty se vztahují na všechny obecné aplikace, ve kterých je možné sadu SDK použít, včetně webových aplikací a konzolových aplikací.These concepts apply to any general application where the SDK can be used including web apps and console apps.

Odesílají se metriky.Sending metrics

Obsah souboru nahraďte worker.cs následujícím:Replace the contents of your worker.cs file with the following:

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

Pokud spustíte výše uvedený kód a budete sledovat telemetrii, která je odesílána prostřednictvím okna výstupu sady Visual Studio, nebo pomocí nástroje, jako je Fiddler Telerik, uvidíte, že Smyčka while bude opakovaně prováděna bez odeslání telemetrie a pak bude jedna položka telemetrie odeslána pomocí značky 60-sekund, který v případě našeho testu vypadá takto. :If you run the code above and watch the telemetry being sent via the Visual Studio output window or a tool like Telerik's Fiddler, you will see the while loop repeatedly executing with no telemetry being sent and then a single telemetry item will be sent by around the 60-second mark, which in the case of our test looks as follows:

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 jediná položka telemetrie představuje agregaci 41 různých měření metriky.This single telemetry item represents an aggregate of 41 distinct metric measurements. Vzhledem k tomu, že jsme přeposlali stejnou hodnotu znovu a znovu, máme směrodatnou odchylku (stDev) 0 se stejnými hodnotami maxima (max) a minimum (min) .Since we were sending the same value over and over again we have a standard deviation (stDev) of 0 with an identical maximum (max), and minimum (min) values. Vlastnost Value představuje součet všech hodnot, které byly agregovány.The value property represents a sum of all the individual values that were aggregated.

Pokud prověříme náš Application Insights prostředek v prostředí log (Analytics), bude tato samostatná položka telemetrie vypadat takto:If we examine our Application Insights resource in the Logs (Analytics) experience, this individual telemetry item would look as follows:

Zobrazení dotazu Log Analytics

Poznámka

I když nezpracovaná položka telemetrie neobsahovala explicitní vlastnost Sum nebo pole, vytvoříme pro vás jednu.While the raw telemetry item did not contain an explicit sum property/field once ingested we create one for you. V tomto případě value valueSum představuje vlastnost i stejnou věc.In this case both the value and valueSum property represent the same thing.

K vlastní telemetrii metriky můžete také přistupovat v části metriky na portálu.You can also access your custom metric telemetry in the Metrics section of the portal. Jak v závislosti na protokolu, tak i ve vlastní metrikě.As both a log-based, and custom metric. (Na snímku obrazovky níže je příklad založený na protokolu.) Zobrazení Průzkumníka metrik(The screenshot below is an example of log-based.) Metrics explorer view

Ukládání referenčních informací metriky do mezipaměti pro použití s vysokou propustnostíCaching metric reference for high-throughput usage

V některých případech jsou hodnoty metriky pozorovány velmi často.In some cases metric values are observed very frequently. Například služba s vysokou propustností, která zpracovává 500 požadavků za sekundu, může chtít vygenerovat 20 metrik telemetrie pro každý požadavek.For example, a high-throughput service that processes 500 requests/second may want to emit 20 telemetry metrics for each request. To znamená sledování hodnot 10 000 za sekundu.This means tracking 10,000 values per second. V takových scénářích s vysokou propustností můžou uživatelé potřebovat sadu SDK, aby vyloučí některá hledání.In such high-throughput scenarios, users may need to help the SDK by avoiding some lookups.

V tomto případě příklad provedl vyhledávání pro popisovač metriky "ComputersSold" a následně sledoval zjištěnou hodnotu 42.For example, in this case, the example above performed a lookup for a handle for the metric "ComputersSold" and then tracked an observed value 42. Místo toho může být popisovač uložen do mezipaměti pro více volání sledování:Instead, the handle may be cached for multiple track invocations:

//...

        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 metrik do mezipaměti je výše uvedený příklad také snížen na Task.Delay 50 milisekund, aby smyčka prováděla častěji v důsledku 772 TrackValue() vyvolání.In addition to caching the metric handle, the example above also reduced the Task.Delay to 50 milliseconds so that the loop would execute more frequently resulting in 772 TrackValue() invocations.

Multidimenzionální metrikyMulti-dimensional metrics

Příklady v předchozí části ukazují nulové multidimenzionální metriky.The examples in the previous section show zero-dimensional metrics. Metriky mohou být také multidimenzionální.Metrics can also be multi-dimensional. V současné době podporujeme až 10 dimenzí.We currently support up to 10 dimensions.

Tady je příklad vytvoření jednorozměrné metriky:Here is an example of how to create a one-dimensional metric:

//...

        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í tohoto kódu pro minimálně 60 sekund bude mít za následek, že se do Azure pošle tři různé položky telemetrie, z nichž každá představuje agregaci jednoho ze tří faktorů formuláře.Running this code for at least 60 seconds will result in three distinct telemetry items being sent to Azure, each representing the aggregation of one of the three form factors. Stejně jako předtím je můžete prozkoumávat v zobrazení protokolů (Analytics):As before you can examine these in Logs (Analytics) view:

Zobrazení Log Analytics multidimenzionální metriky

A také v prostředí Průzkumníka metrik:As well as in the Metrics explorer experience:

Vlastní metriky

Všimněte si ale, že nebudete schopni rozdělit metriku podle vaší nové vlastní dimenze nebo zobrazit vlastní dimenzi pomocí zobrazení metrik:However, you will notice that you aren't able to split the metric by your new custom dimension, or view your custom dimension with the metrics view:

Rozdělení podpory

Ve výchozím nastavení se multidimenzionální metriky v prostředí metrického Průzkumníka nezapnou v Application Insights prostředky.By default multi-dimensional metrics within the Metric explorer experience are not turned on in Application Insights resources.

Zapnout multidimenzionální metrikyEnable multi-dimensional metrics

Pokud chcete pro prostředek Application Insights povolit multidimenzionální metriky, vyberte využití a odhadované náklady. > vlastní metriky > umožňují upozorňování na vlastní dimenze metriky > OK.To enable multi-dimensional metrics for an Application Insights resource, Select Usage and estimated costs > Custom Metrics > Enable alerting on custom metric dimensions > OK. Další podrobnosti najdete tady.More details about this can be found here.

Po provedení této změny a odeslání nové multidimenzionální telemetrie budete moci použít rozdělení.Once you have made that change and send new multi-dimensional telemetry, you will be able to Apply splitting.

Poznámka

Po zapnutí funkce na portálu budou mít dimenze uložené jenom nově odeslané metriky.Only newly sent metrics after the feature was turned on in the portal will have dimensions stored.

Použít rozdělení

A zobrazte agregace metrik pro každou dimenzi FormFactor :And view your metric aggregations for each FormFactor dimension:

Faktory formuláře

Jak používat MetricIdentifier, pokud existuje více než tři dimenzeHow to use MetricIdentifier when there are more than three dimensions

V současné době je dostupná 10 dimenzí, ale více než tři dimenze vyžaduje použití MetricIdentifier :Currently 10 dimensions are supported however, greater than three dimensions requires the use of 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");

Konfigurace vlastní metrikyCustom metric configuration

Pokud chcete změnit konfiguraci metriky, musíte to udělat v místě, kde je metrika inicializovaná.If you want to alter the metric configuration, you need to do this in the place where the metric is initialized.

Speciální názvy dimenzíSpecial dimension names

Metriky nepoužívají kontext telemetrie pro TelemetryClient použití pro přístup k nim, speciální názvy dimenzí, které jsou k dispozici jako konstanty ve MetricDimensionNames třídě, jsou nejlepším řešením pro toto omezení.Metrics do not use the telemetry context of the TelemetryClient used to access them, special dimension names available as constants in MetricDimensionNames class is the best workaround for this limitation.

Agregace metrik odesílané níže "velikost požadavku na speciální operaci" – metrika nebude mít Context.Operation.Name nastavenou hodnotu "speciální operace".Metric aggregates sent by the below "Special Operation Request Size"-metric will not have their Context.Operation.Name set to "Special Operation". Vzhledem k tomu, že TrackMetric() nebo jakýkoli jiný TrackXXX () bude OperationName správně nastaven na "speciální operace".Whereas TrackMetric() or any other TrackXXX() will have OperationName set correctly to "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 takovém případě použijte názvy zvláštních dimenzí uvedené ve třídě, aby MetricDimensionNames bylo možné zadat TelemetryContext hodnoty.In this circumstance, use the special dimension names listed in the MetricDimensionNames class in order to specify TelemetryContext values.

Například při odeslání agregované metriky z dalšího příkazu do koncového bodu Application Insights cloudu Context.Operation.Name bude jeho datové pole nastaveno na "speciální operace":For example, when the metric aggregate resulting from the next statement is sent to the Application Insights cloud endpoint, its Context.Operation.Name data field will be set to "Special Operation":

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

Hodnoty této speciální dimenze budou zkopírovány do objektu a nebudou TelemetryContext použity jako dimenze ' Normal '.The values of this special dimension will be copied into the TelemetryContext and will not be used as a 'normal' dimension. Pokud chcete také zachovat dimenzi operace pro normální zkoumání metriky, musíte pro tento účel vytvořit samostatnou dimenzi:If you want to also keep an operation dimension for normal metric exploration, you need to create a separate dimension for that purpose:

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

Dimenze a časová řada cappingDimension and time-series capping

Pokud nechcete, aby subsystém telemetrie omylem používal vaše prostředky, můžete řídit maximální počet datových řad na metriku.To prevent the telemetry subsystem from accidentally using up your resources, you can control the maximum number of data series per metric. Výchozí omezení nejsou na více než 1000 celkových datových řad na jednu metriku a maximálně 100 různých hodnot na dimenzi.The default limits are no more than 1000 total data series per metric, and no more than 100 different values per dimension.

V kontextu dimenzí a časových řad capping používáme k zajištění Metric.TrackValue(..) dodržování limitů.In the context of dimension and time series capping we use Metric.TrackValue(..) to make sure that the limits are observed. Pokud jsou limity již dosaženy, Metric.TrackValue(..) vrátí hodnotu false a hodnota nebude sledována.If the limits are already reached, Metric.TrackValue(..) will return "False" and the value will not be tracked. V opačném případě vrátí "true".Otherwise it will return "True". To je užitečné, pokud data metriky pocházejí ze vstupu uživatele.This is useful if the data for a metric originates from user input.

MetricConfigurationKonstruktor přebírá některé možnosti pro správu různých řad v rámci příslušné metriky a objektu IMetricSeriesConfiguration , který implementuje třídu, která určuje chování agregace pro každou jednotlivou sérii metriky:The MetricConfiguration constructor takes some options on how to manage different series within the respective metric and an object of a class implementing IMetricSeriesConfiguration that specifies aggregation behavior for each individual series of the metric:

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.
  • seriesCountLimitje maximální počet datových řad časových řad, které může metrika obsahovat.seriesCountLimit is the max number of data time series a metric can contain. Po dosažení tohoto limitu volání TrackValue() .Once this limit is reached, calls to TrackValue().
  • valuesPerDimensionLimitpodobným způsobem omezuje počet jedinečných hodnot na dimenzi.valuesPerDimensionLimit limits the number of distinct values per dimension in a similar manner.
  • restrictToUInt32ValuesUrčuje, zda mají být sledovány pouze nezáporné celočíselné hodnoty.restrictToUInt32Values determines whether or not only non-negative integer values should be tracked.

Tady je příklad, jak odeslat zprávu s upozorněním na překročení limitu zakončení:Here is an example of how to send a message to know if cap limits are exceeded:

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ší krokyNext steps