Collecte de métriques personnalisées dans .NET et .NET Core
Les kits SDK .NET et .NET Core Azure Monitor Application Insights offrent deux méthodes de collecte des métriques personnalisées, TrackMetric()
et GetMetric()
. La principale différence entre ces deux méthodes est l’agrégation locale. La méthode TrackMetric()
n’effectue pas de pré-agrégation. La méthode GetMetric()
effectue une pré-agrégation. Nous vous recommandons d’utiliser l’agrégation, donc TrackMetric()
n’est plus la méthode préférée de collecte des métriques personnalisées. Cet article vous guide dans l'utilisation de la méthode GetMetric()
et vous expliquera son fonctionnement.
Remarque
La documentation suivante s’appuie sur l’API classique d’Application Insights. Le plan à long terme pour Application Insights est de collecter des données en utilisant OpenTelemetry. Pour plus d’informations, consultez Activer Azure Monitor OpenTelemetry pour les applications .NET, Node.js, Python et Java et notre feuille de route OpenTelemetry. L’aide sur la migration est disponible pour .NET, Node.js et Python.
API avec pré-agrégation et API sans pré-agrégation
La méthode TrackMetric()
envoie des données de télémétrie brutes indiquant une métrique. L’envoi d’un seul élément de télémétrie pour chaque valeur n’est pas efficace. La méthode TrackMetric()
est également inefficace en termes de performances, car chaque TrackMetric(item)
transite par le pipeline de SDK complet des initialiseurs et des processeurs de télémétrie.
Contrairement à TrackMetric()
, GetMetric()
gère la pré-agrégation locale pour vous et envoie ensuite seulement une métrique récapitulative agrégée à un intervalle fixe d’une minute. Si vous avez besoin de superviser étroitement une métrique personnalisée au niveau de la seconde ou même de la milliseconde, vous pouvez le faire tout en n’encourant que le coût de stockage et de trafic réseau de la supervision à intervalle d’une minute. Ce comportement réduit aussi considérablement le risque de limitation, car le nombre total d’éléments de télémétrie à envoyer pour une métrique agrégée est fortement réduit.
Dans Application Insights, les métriques personnalisées collectées par le biais de TrackMetric()
et GetMetric()
ne sont pas soumises à l’échantillonnage. L’échantillonnage de métriques importantes peut entraîner des scénarios dans lesquels les alertes que vous avez créées autour de ces métriques peuvent devenir peu fiables. En n’échantillonnant jamais vos métriques personnalisées, vous pouvez généralement être sûr que quand vos seuils d’alerte sont enfreints, une alerte se déclenche. Parce que les métriques personnalisées ne sont pas échantillonnées, il existe des problèmes potentiels.
Le suivi des tendances dans une métrique chaque seconde, ou à un intervalle encore plus détaillé, peut secondes, ou à un intervalle encore plus granulaire, peut entraîner :
- Une augmentation des coûts de stockage de données. Un coût est associé à la quantité de données que vous envoyez à Azure Monitor. Plus vous envoyez de données, plus le coût global de supervision est élevé.
- Une augmentation du trafic réseau ou une surcharge de performance. Dans certains scénarios, cette surcharge peut avoir des conséquences en termes de performances d’application et un coût financier.
- Un risque de limitation de l’ingestion. Azure Monitor supprime (« limite ») des points de données quand votre application envoie un taux de télémétrie élevé dans un court laps de temps.
La limitation constitue une préoccupation car elle peut entraîner un non-signalement des alertes. La condition nécessaire au déclenchement d’une alerte peut se produire localement, puis être supprimée au point de terminaison d’ingestion en raison d’un trop grand nombre de données envoyées. Nous ne recommandons pas l’utilisation de TrackMetric()
pour .NET et .NET Core, sauf si vous avez implémenté votre propre logique d’agrégation locale. Si vous essayez de suivre chaque occurrence d’un événement sur une période donnée, vous constaterez peut-être que TrackEvent()
est plus adaptée. Toutefois, n’oubliez pas que contrairement aux métriques personnalisées, les événements personnalisés sont soumis à l’échantillonnage. Vous pouvez néanmoins toujours utiliser TrackMetric()
même sans écrire votre propre pré-agrégation locale. Mais si vous le faites, soyez conscient des pièges.
En résumé, nous recommandons GetMetric()
, car elle effectue une pré-agrégation : elle accumule les valeurs de tous les appels de Track()
et envoie un résumé/agrégat une fois par minute. La méthode GetMetric()
peut réduire considérablement le coût et l'impact sur les performances en envoyant moins de points de données, tout en recueillant néanmoins toutes les informations pertinentes.
Notes
Seuls les kits SDK .NET et .NET Core ont une méthode GetMetric()
. Si vous utilisez Java, consultez Envoi de métriques personnalisées à l’aide de micromètre. Pour JavaScript et Node.js, vous utiliserez quand même TrackMetric()
, mais gardez à l’esprit les avertissements décrits dans la section précédente. Pour Python, vous pouvez utiliser OpenCensus.stats pour envoyer des métriques personnalisées, mais l’implémentation de métriques est différente.
Bien démarrer avec GetMetric
Pour nos exemples, nous allons utiliser une application de service Worker .NET Core 3.1 de base. Si vous souhaitez reproduire l’environnement de test utilisé avec ces exemples, suivez les étapes 1 à 6 de l’article Monitoring worker service. Ces étapes permettent d'ajouter Application Insights à un modèle de projet de service worker de base. Ces concepts s’appliquent à toute application générale dans laquelle le SDK peut être utilisé, notamment les applications web et les applications de console.
Envoyer des mesures
Remplacez le contenu de votre fichier worker.cs
par le code suivant :
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);
}
}
}
}
Lors de l’exécution de l’exemple de code, vous voyez la boucle while
s'exécuter de manière répétée sans qu'aucune télémétrie ne soit envoyée dans la fenêtre de sortie Visual Studio. Un seul élément de télémétrie est envoyé vers la marque de 60 secondes, qui, dans notre test, se présente comme suit :
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"}}}}
Cet élément de télémétrie unique représente une agrégation de 41 mesures de métriques distinctes. Puisque nous envoyions sans cesse la même valeur, nous avons un écart type (stDev
) de 0
avec des valeurs maximale (max
) et minimale (min
) identiques. La propriété value
représente la somme de toutes les valeurs individuelles qui ont été agrégées.
Notes
La méthode GetMetric
ne prend pas en charge le suivi de la dernière valeur (par exemple, gauge
) ou le suivi des histogrammes ou des distributions.
Si nous examinons notre ressource Application Insights dans l’expérience Logs (Analytics), l’élément de télémétrie individuel ressemblerait à la capture d'écran suivante.
Notes
Si l’élément de télémétrie brut ne contenait pas de champ ou de propriété de somme explicite une fois ingéré, nous en créons un pour vous. En l’occurrence, la propriété value
et valueSum
représentent la même chose.
Vous pouvez également accéder à vos données de télémétrie de métriques personnalisées dans la section Métriques du portail, à la fois en tant que métrique personnalisée et basée sur un journal. La capture d’écran suivante est un exemple de métrique basée sur un journal.
Référence de métrique de mise en cache pour une utilisation à haut débit
Des valeurs métriques peuvent être observées fréquemment dans certains cas. Par exemple, un service à haut débit qui traite 500 requêtes par seconde peut vouloir émettre 20 métriques de télémétrie pour chaque requête. Le résultat signifie qu’il faut effectuer le suivi de 10 000 valeurs par seconde. Dans de tels scénarios à haut débit, les utilisateurs peuvent avoir besoin d'aider le kit de développement logiciel (SDK) en évitant certaines recherches.
Par exemple, l’exemple ci-dessus a effectué une recherche pour un descripteur pour la métrique ComputersSold
, puis a suivi une valeur observée 42
. Au lieu de cela, le descripteur peut être mis en cache pour plusieurs appels de suivi :
//...
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);
}
}
Outre la mise en cache du descripteur de métrique, l’exemple ci-dessus a également réduit Task.Delay
à 50 millisecondes, de sorte que la boucle s’exécute plus fréquemment. Le résultat est 772 TrackValue()
appels.
Métriques multidimensionnelles
Les exemples de la section précédente présentent des métriques à zéro dimension. Les métriques peuvent également être multidimensionnelles. Nous prenons actuellement en charge jusqu’à 10 dimensions.
Voici un exemple qui illustre comment créer une métrique unidimensionnelle :
//...
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);
}
}
L'exécution de l'exemple de code pendant au moins 60 secondes entraîne l'envoi de trois éléments télémétriques distincts à Azure. Chaque élément représente l’agrégation de l’un des trois facteurs de forme. Comme auparavant, vous pouvez les examiner plus en détail dans la vue Logs (Analytics) :
Dans l'explorateur de métriques :
Remarquez que vous ne pouvez pas diviser la métrique en fonction de votre nouvelle dimension personnalisée, ni afficher votre dimension personnalisée avec la vue des métriques.
Par défaut, les métriques multidimensionnelles dans l’explorateur de métriques ne sont pas activées dans les ressources Application Insights.
Activer les métriques multidimensionnelles
Pour activer les métriques multidimensionnelles pour une ressource Application Insights, sélectionnez Utilisation et estimation des coûts>Métriques personnalisées>Activer les alertes sur les dimensions des métriques personnalisées>OK. Pour plus d’informations, consultez Dimensions de métriques personnalisées et pré-agrégation.
Après avoir effectué cette modification et envoyé de nouvelles données de télémétrie multidimensionnelles, vous pouvez sélectionner Appliquer le fractionnement.
Notes
Seules les métriques envoyées après l’activation de la fonctionnalité dans le portail auront des dimensions stockées.
Affichez vos agrégations de métriques pour chaque FormFactor
dimension.
Utilisez MetricIdentifier lorsqu'il y a plus de trois dimensions
Actuellement, 10 dimensions sont supportées. Plus de trois dimensions nécessitent l'utilisation deMetricIdentifier
:
// 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");
Configuration de métrique personnalisée
Si vous souhaitez modifier la configuration des métriques, vous devez apporter des modifications à l'endroit où la métrique est initialisée.
Noms de dimensions spéciales
Les métriques n’utilisent pas le contexte de télémétrie du TelemetryClient
utilisé pour y accéder. Utiliser des noms de dimension spéciaux disponibles comme constantes dans la MetricDimensionNames
classe est la meilleure solution de contournement pour cette limitation.
Les agrégats de métriques envoyés par la métrique suivante Special Operation Request Size
n’auront pas la valeur Context.Operation.Name
définie sur Special Operation
. La TrackMetric()
méthode ou toute autre méthode TrackXXX()
aura OperationName
correctement défini sur 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);
//...
}
}
Dans cette situation, utilisez les noms de dimensions spéciales listés dans la classe MetricDimensionNames
pour spécifier des valeurs TelemetryContext
.
Par exemple, quand l’agrégation de métriques résultant de l’instruction suivante est envoyé au point de terminaison cloud Application Insights, son champ de données Context.Operation.Name
est défini sur Special Operation
:
_telemetryClient.GetMetric("Request Size", MetricDimensionNames.TelemetryContext.Operation.Name).TrackValue(requestSize, "Special Operation");
Les valeurs de cette dimension spéciale sont copiées dans TelemetryContext
et ne seront pas utilisées comme dimension normale. Si vous souhaitez également conserver une dimension d’opération pour l’exploration normale des métriques, vous devez créer une dimension distincte à cet effet :
_telemetryClient.GetMetric("Request Size", "Operation Name", MetricDimensionNames.TelemetryContext.Operation.Name).TrackValue(requestSize, "Special Operation", "Special Operation");
Limitation des dimensions et des séries chronologiques
Pour empêcher que le sous-système de télémétrie n’utilise accidentellement vos ressources, vous pouvez contrôler la quantité maximale de séries de données par métrique. Les limites par défaut sont un maximum de 1 000 séries de données au total par métrique, et un maximum de 100 valeurs différentes par dimension.
Important
Utilisez des valeurs cardinales faibles pour les dimensions afin d’éviter la limitation.
Dans le contexte de la limitation des séries chronologiques et des dimensions, nous utilisons Metric.TrackValue(..)
pour nous assurer que les limites sont respectées. Si les limites sont déjà atteintes, Metric.TrackValue(..)
affiche False
et la valeur n’est pas suivie. Sinon, True
est retourné. Ce comportement est utile si les données d’une métrique proviennent d’une entrée d’utilisateur.
Le constructeur MetricConfiguration
accepte certaines options relatives à la façon de gérer différentes séries au sein de la métrique et un objet d’une classe implémentant IMetricSeriesConfiguration
qui spécifie le comportement d’agrégation pour chaque série de la métrique :
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
est la quantité maximale de séries chronologiques de données qu’une métrique peut contenir. Lorsque cette limite atteinte, les appels àTrackValue()
qui aboutissent normalement à une nouvelle série renvoientfalse
.valuesPerDimensionLimit
limite le nombre de valeurs distinctes par dimension d’une manière similaire.restrictToUInt32Values
détermine si seules les valeurs entières non négatives doivent être suivies.
Voici un exemple qui illustre comment envoyer un message pour savoir si les limites sont dépassées :
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);
}
Étapes suivantes
- Métriques - Get - API REST
- API Application Insights pour les événements et les mesures personnalisés
- En savoir plus sur la supervision des applications de service worker.
- Utilisez des métriques basées sur les journaux et pré-agrégées.
- Analysez les métriques avec l’explorateur de métriques.
- Apprenez comment activer Application Insights pour les applications ASP.NET Core.
- Apprenez comment activer Application Insights pour les applications ASP.NET.