Aangepaste verzameling metrische gegevens in .NET en .NET Core

De Azure Monitor Application Insights .NET- en .NET Core SDK's hebben twee verschillende methoden voor het verzamelen van aangepaste metrische gegevens: TrackMetric() en GetMetric(). Het belangrijkste verschil tussen deze twee methoden is lokale aggregatie. De TrackMetric() methode ontbreekt vooraf aggregatie. De GetMetric() methode heeft vooraf aggregatie. U wordt aangeraden aggregatie te gebruiken, dus TrackMetric() is dit niet langer de voorkeursmethode voor het verzamelen van aangepaste metrische gegevens. In dit artikel wordt u begeleid bij het gebruik van de GetMetric() methode en een aantal van de logica achter de werking ervan.

Notitie

De volgende documentatie is afhankelijk van de klassieke Application Insights-API. Het langetermijnplan voor Application Insights is het verzamelen van gegevens met behulp van OpenTelemetry. Zie Azure Monitor OpenTelemetry inschakelen voor .NET-, Node.js-, Python- en Java-toepassingen voor meer informatie.

Api vooraf aggregeren versus niet-vooraf aggregeren

Met de TrackMetric() methode worden onbewerkte telemetriegegevens verzonden die een metrische waarde aanduidt. Het is inefficiënt om één telemetrie-item voor elke waarde te verzenden. De TrackMetric() methode is ook inefficiënt in termen van prestaties, omdat elke TrackMetric(item) sdk-pijplijn van telemetrie-initializers en processors doorloopt.

In tegenstelling tot TrackMetric(), GetMetric() verwerkt lokale vooraggregatie voor u en verzendt vervolgens alleen een geaggregeerde samenvattingsmetriek met een vast interval van één minuut. Als u een aantal aangepaste metrische gegevens op het niveau van de tweede of zelfs milliseconden nauwkeurig wilt bewaken, kunt u dit doen, terwijl u alleen de kosten voor opslag en netwerkverkeer van elke minuut hoeft te bewaken. Dit gedrag vermindert ook het risico op beperking aanzienlijk omdat het totale aantal telemetrie-items dat moet worden verzonden voor een geaggregeerde metriek aanzienlijk wordt verminderd.

In Application Insights worden aangepaste metrische gegevens verzameld via TrackMetric() en GetMetric() zijn ze niet onderworpen aan steekproeven. Het nemen van belangrijke metrische gegevens kan leiden tot scenario's waarin waarschuwingen die u mogelijk hebt gebouwd rond die metrische gegevens onbetrouwbaar kunnen worden. Door nooit een steekproef te nemen van uw aangepaste metrische gegevens, kunt u er over het algemeen zeker van zijn dat wanneer uw waarschuwingsdrempels worden overschreden, een waarschuwing wordt geactiveerd. Omdat er geen voorbeeld van aangepaste metrische gegevens wordt genomen, zijn er enkele mogelijke problemen.

Bijhouden van trend in een metriek elke seconde, of met een nog gedetailleerder interval, kan het volgende tot gevolg hebben:

  • Hogere kosten voor gegevensopslag. Er zijn kosten verbonden aan de hoeveelheid gegevens die u naar Azure Monitor verzendt. Hoe meer gegevens u verzendt, hoe groter de totale kosten van bewaking.
  • Verhoogde netwerkverkeer of prestatieoverhead. In sommige scenario's kan deze overhead zowel kosten voor geld- als toepassingsprestaties hebben.
  • Risico op opnamebeperking. Azure Monitor daalt gegevenspunten ('vertragingsbeperkingen') wanneer uw app een hoge snelheid van telemetrie verzendt in een kort tijdsinterval.

Beperking is een probleem omdat dit kan leiden tot gemiste waarschuwingen. De voorwaarde voor het activeren van een waarschuwing kan lokaal optreden en vervolgens worden verwijderd bij het opname-eindpunt omdat er te veel gegevens worden verzonden. Het wordt afgeraden om voor .NET en .NET Core te gebruiken TrackMetric() , tenzij u uw eigen lokale aggregatielogica hebt geïmplementeerd. Als u elk exemplaar wilt bijhouden dat een gebeurtenis plaatsvindt gedurende een bepaalde periode, is dat TrackEvent() misschien beter geschikt. Houd er rekening mee dat in tegenstelling tot aangepaste metrische gegevens aangepaste gebeurtenissen onderhevig zijn aan steekproeven. U kunt nog steeds gebruiken TrackMetric() , zelfs zonder uw eigen lokale aggregatie vooraf te schrijven. Maar als je dat doet, wees je bewust van de valkuilen.

Kortom, we raden u aan GetMetric() om vooraf te aggregeren, maar ook waarden van alle Track() aanroepen samen te voegen en een samenvatting/aggregatie eenmaal per minuut te verzenden. De GetMetric() methode kan de kosten- en prestatieoverhead aanzienlijk verlagen door minder gegevenspunten te verzenden terwijl alle relevante informatie nog steeds wordt verzameld.

Notitie

Alleen de .NET- en .NET Core SDK's hebben een GetMetric() methode. Als u Java gebruikt, raadpleegt u Aangepaste metrische gegevens verzenden met behulp van micrometer. Voor JavaScript en Node.js zou u nog steeds gebruiken TrackMetric(), maar houd rekening met de opmerkingen die in de vorige sectie zijn beschreven. Voor Python kunt u OpenCensus.stats gebruiken om aangepaste metrische gegevens te verzenden, maar de implementatie van metrische gegevens verschilt.

Aan de slag met GetMetric

Voor onze voorbeelden gebruiken we een eenvoudige .NET Core 3.1-werkservicetoepassing. Als u de testomgeving wilt repliceren die met deze voorbeelden wordt gebruikt, volgt u stap 1-6 in het artikel over de bewakingswerkrolservice. Met deze stappen voegt u Application Insights toe aan een sjabloon voor een basiswerkserviceproject. De concepten zijn van toepassing op elke algemene toepassing waar de SDK kan worden gebruikt, met inbegrip van web-apps en console-apps.

Metrische gegevens verzenden

Vervang de inhoud van het worker.cs bestand door de volgende code:

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

Wanneer u de voorbeeldcode uitvoert, ziet u dat de while lus herhaaldelijk wordt uitgevoerd zonder dat er telemetrie wordt verzonden in het uitvoervenster van Visual Studio. Eén telemetrie-item wordt verzonden met ongeveer 60 seconden, die in onze test er als volgt uitziet:

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

Dit enkele telemetrie-item vertegenwoordigt een aggregaties van 41 afzonderlijke metrische metingen. Omdat we steeds dezelfde waarde hebben verzonden, hebben we een standaarddeviatie (stDev) van 0 identieke maximumwaarden (max) en minimumwaarden (min). De value eigenschap vertegenwoordigt een som van alle afzonderlijke waarden die zijn samengevoegd.

Notitie

De GetMetric methode biedt geen ondersteuning voor het bijhouden van de laatste waarde (bijvoorbeeld gauge) of het bijhouden van histogrammen of distributies.

Als we onze Application Insights-resource in de ervaring Logboeken (Analytics) onderzoeken, ziet het afzonderlijke telemetrie-item eruit als in de volgende schermopname.

Screenshot that shows the Log Analytics query view.

Notitie

Hoewel het onbewerkte telemetrie-item geen expliciete someigenschap/-veld bevat nadat deze is opgenomen, maken we er een voor u. In dit geval vertegenwoordigen zowel de eigenschap als valueSum de value eigenschap hetzelfde.

U kunt ook toegang krijgen tot uw aangepaste metrische telemetrie in de sectie Metrische gegevens van de portal als een op logboek gebaseerde en aangepaste metrische gegevens. De volgende schermopname is een voorbeeld van een metrische gegevens op basis van een logboek.

Screenshot that shows the Metrics explorer view.

Naslaginformatie over metrische cachegegevens voor gebruik met hoge doorvoer

In sommige gevallen kunnen metrische waarden vaak worden waargenomen. Een service met hoge doorvoer die bijvoorbeeld 500 aanvragen per seconde verwerkt, wil mogelijk 20 metrische gegevens voor telemetrie verzenden voor elke aanvraag. Het resultaat betekent dat er 10.000 waarden per seconde worden bijgehouden. In dergelijke scenario's met hoge doorvoer moeten gebruikers mogelijk de SDK helpen door bepaalde zoekacties te voorkomen.

In het voorgaande voorbeeld is bijvoorbeeld een zoekactie uitgevoerd voor een ingang voor de metrische waarde ComputersSold en vervolgens een waargenomen waarde bijgehouden.42 In plaats daarvan kan de greep worden opgeslagen in de cache voor meerdere aanroepen van tracering:

//...

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

Naast het opslaan van de metrische ingang in de cache, is het voorgaande voorbeeld ook gereduceerd Task.Delay tot 50 milliseconden, zodat de lus vaker zou worden uitgevoerd. Het resultaat is 772 TrackValue() aanroepen.

Multidimensionale metrische gegevens

In de voorbeelden in de vorige sectie worden nuldimensionale metrische gegevens weergegeven. Metrische gegevens kunnen ook multidimensionaal zijn. Momenteel ondersteunen we maximaal 10 dimensies.

Hier volgt een voorbeeld van het maken van een eendimensionale metrische waarde:

//...

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

Het uitvoeren van de voorbeeldcode voor ten minste 60 seconden resulteert in drie afzonderlijke telemetrie-items die naar Azure worden verzonden. Elk item vertegenwoordigt de aggregatie van een van de drie formulierfactoren. Net als voorheen kunt u verder onderzoeken in de weergave Logboeken (Analyse).

Screenshot that shows the Log Analytics view of multidimensional metric.

In de Metrics Explorer:

Screenshot that shows Custom metrics.

U kunt de metrische waarde niet splitsen door uw nieuwe aangepaste dimensie of uw aangepaste dimensie weergeven met de weergave met metrische gegevens.

Screenshot that shows splitting support.

Multidimensionale metrische gegevens in de Metric Explorer zijn standaard niet ingeschakeld in Application Insights-resources.

Multidimensionale metrische gegevens inschakelen

Als u multidimensionale metrische gegevens wilt inschakelen voor een Application Insights-resource, selecteert u Gebruik en geschatte kosten aangepaste metrische>gegevens. Schakel waarschuwingen in voor aangepaste metrische dimensies>>OK. Zie Aangepaste dimensies voor metrische gegevens en vooraggregatie voor meer informatie.

Nadat u deze wijziging hebt aangebracht en nieuwe multidimensionale telemetrie hebt verzonden, kunt u Splitsen toepassen selecteren.

Notitie

Alleen nieuw verzonden metrische gegevens nadat de functie is ingeschakeld in de portal, worden dimensies opgeslagen.

Screenshot that shows applying splitting.

Bekijk uw metrische aggregaties voor elke FormFactor dimensie.

Screenshot that shows form factors.

MetricIdentifier gebruiken wanneer er meer dan drie dimensies zijn

Momenteel worden 10 dimensies ondersteund. Voor meer dan drie dimensies is het gebruik van 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");

Aangepaste configuratie van metrische gegevens

Als u de configuratie van metrische gegevens wilt wijzigen, moet u wijzigingen aanbrengen op de plaats waar de metrische waarde wordt geïnitialiseerd.

Speciale dimensienamen

Metrische gegevens gebruiken niet de telemetriecontext van de TelemetryClient gebruikte gegevens om ze te openen. Het gebruik van speciale dimensienamen die beschikbaar zijn als constanten in de MetricDimensionNames klasse, is de beste tijdelijke oplossing voor deze beperking.

Metrische statistische gegevens die door de volgende Special Operation Request Size metrische gegevens worden verzonden, zijn Context.Operation.Name niet ingesteld op Special Operation. De TrackMetric() methode of een andere TrackXXX() methode is OperationName correct ingesteld op 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);
                //...
            }
                   
        }

Gebruik in dit geval de speciale dimensienamen die in de MetricDimensionNames klasse worden vermeld om de TelemetryContext waarden op te geven.

Wanneer de statistische waarde die het resultaat is van de volgende instructie bijvoorbeeld naar het Application Insights-cloudeindpunt wordt verzonden, Context.Operation.Name wordt het gegevensveld ingesteld op Special Operation:

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

De waarden van deze speciale dimensie worden gekopieerd TelemetryContext en worden niet gebruikt als een normale dimensie. Als u ook een bewerkingsdimensie wilt behouden voor normale metrische gegevensverkenning, moet u hiervoor een afzonderlijke dimensie maken:

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

Dimensie- en tijdreekslimieten

Als u wilt voorkomen dat het subsysteem voor telemetrie per ongeluk uw resources gebruikt, kunt u het maximum aantal gegevensreeksen per metrische waarde beheren. De standaardlimieten zijn niet meer dan 1000 totale gegevensreeksen per metrische waarde en niet meer dan 100 verschillende waarden per dimensie.

Belangrijk

Gebruik lage kardinaliteiten voor dimensies om beperking te voorkomen.

In de context van dimensie- en tijdreekslimieten gebruiken Metric.TrackValue(..) we om ervoor te zorgen dat de limieten worden waargenomen. Als de limieten False al zijn bereikt, Metric.TrackValue(..) worden de waarden geretourneerd en wordt de waarde niet bijgehouden. Anders wordt het geretourneerd True. Dit gedrag is handig als de gegevens voor een metrische waarde afkomstig zijn van gebruikersinvoer.

De MetricConfiguration constructor gebruikt enkele opties voor het beheren van verschillende reeksen binnen de respectieve metrische gegevens en een object van een klasse die IMetricSeriesConfiguration het aggregatiegedrag opgeeft voor elke afzonderlijke reeks van de metrische gegevens:

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 is het maximum aantal gegevenstijdreeksen dat een metrische waarde kan bevatten. Wanneer deze limiet is bereikt, retourneren aanroepen naar TrackValue() die normaal gesproken een nieuwe reeks.false
  • valuesPerDimensionLimit beperkt het aantal afzonderlijke waarden per dimensie op een vergelijkbare manier.
  • restrictToUInt32Values bepaalt of niet alleen niet-negatieve gehele getallen moeten worden bijgehouden.

Hier volgt een voorbeeld van hoe u een bericht verzendt om te weten of limieten voor limieten worden overschreden:

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

Volgende stappen