Bibliothèque cliente Azure Metrics Advisor pour .NET - version 1.1.0

Azure Cognitive Services Metrics Advisor est un service cloud qui utilise le Machine Learning pour surveiller et détecter les anomalies dans les données de série chronologique. Il comprend les fonctionnalités suivantes :

  • Analysez les données multidimensionnelles provenant de plusieurs sources de données.
  • Identifiez et corrélez les anomalies.
  • Configurez et ajustez le modèle de détection des anomalies utilisé sur vos données.
  • Diagnostiquer les anomalies et aider à analyser la cause racine.

| Code sourcePackage (NuGet) | Documentation de référence sur les | API | Documentation produitÉchantillons

Prise en main

Installer le package

Installez la bibliothèque de client Azure Metrics Advisor pour .NET avec NuGet :

dotnet add package Azure.AI.MetricsAdvisor

Prérequis

Créer une ressource Metrics Advisor

Vous pouvez créer une ressource Metrics Advisor à l’aide de :

Option 1 : Portail Azure.

Option 2 : Azure CLI.

Voici un exemple de création d’une ressource Metrics Advisor à l’aide de l’interface CLI :

# Create a new resource group to hold the Metrics Advisor resource.
# If using an existing resource group, skip this step.
az group create --name <your-resource-name> --location <location>
# Create the Metrics Advisor resource.
az cognitiveservices account create \
    --name <your-resource-name> \
    --resource-group <your-resource-group-name> \
    --kind MetricsAdvisor \
    --sku <sku> \
    --location <location>
    --yes

Pour plus d’informations sur la création de la ressource ou sur la façon d’obtenir les informations d’emplacement et de référence, consultez ici.

Authentifier le client

Pour interagir avec le service Metrics Advisor, vous devez créer une instance des MetricsAdvisorClient classes ouMetricsAdvisorAdministrationClient. Vous aurez besoin d’un point de terminaison, d’une clé d’abonnement et d’une clé API pour instancier un objet client.

Obtenir le point de terminaison et la clé d’abonnement

Vous pouvez obtenir le point de terminaison et la clé d’abonnement à partir des informations de ressource dans le portail Azure.

Vous pouvez également utiliser l’extrait de code Azure CLI ci-dessous pour obtenir la clé d’abonnement à partir de la ressource Metrics Advisor.

az cognitiveservices account keys list --resource-group <your-resource-group-name> --name <your-resource-name>

Obtenir la clé API

Vous pouvez obtenir la clé API dans le portail web Metrics Advisor. Vous serez invité à vous connecter pour l’authentification.

Une fois connecté, renseignez le nom de votre ressource Azure Active Directory, Abonnement et Metrics Advisor.

Créer un MetricsAdvisorClient ou un MetricsAdvisorAdministrationClient

Une fois que vous avez l’abonnement et les clés API, créez un MetricsAdvisorKeyCredential. Avec le point de terminaison et les informations d’identification de la clé, vous pouvez créer un MetricsAdvisorClient :

string endpoint = "<endpoint>";
string subscriptionKey = "<subscriptionKey>";
string apiKey = "<apiKey>";
var credential = new MetricsAdvisorKeyCredential(subscriptionKey, apiKey);
var client = new MetricsAdvisorClient(new Uri(endpoint), credential);

Vous pouvez également créer un MetricsAdvisorAdministrationClient pour effectuer des opérations d’administration :

string endpoint = "<endpoint>";
string subscriptionKey = "<subscriptionKey>";
string apiKey = "<apiKey>";
var credential = new MetricsAdvisorKeyCredential(subscriptionKey, apiKey);
var adminClient = new MetricsAdvisorAdministrationClient(new Uri(endpoint), credential);

Créer un MetricsAdvisorClient ou un MetricsAdvisorAdministrationClient avec Azure Active Directory

MetricsAdvisorKeyCredential l’authentification est utilisée dans les exemples de ce guide de prise en main, mais vous pouvez également vous authentifier auprès d’Azure Active Directory à l’aide de la bibliothèque Azure Identity.

Pour utiliser le fournisseur DefaultAzureCredential indiqué ci-dessous ou d’autres fournisseurs d’informations d’identification fournis avec le kit de développement logiciel (SDK) Azure, installez le package Azure.Identity :

Install-Package Azure.Identity

Vous devez également inscrire une nouvelle application AAD et accorder l’accès à Metrics Advisor en attribuant le "Cognitive Services Metrics Advisor User" rôle à votre principal de service. Vous pouvez attribuer le rôle à la "Cognitive Services Metrics Advisor Administrator" place si des privilèges d’administrateur sont requis.

Définissez les valeurs de l’ID client, de l’ID de locataire et de la clé secrète client de l’application AAD en tant que variables d’environnement : AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET.

Une fois que vous avez défini les variables d’environnement, vous pouvez créer un MetricsAdvisorClient:

string endpoint = "<endpoint>";
var client = new MetricsAdvisorClient(new Uri(endpoint), new DefaultAzureCredential());

Vous pouvez également créer un pour effectuer des opérations d’administration MetricsAdvisorAdministrationClient :

string endpoint = "<endpoint>";
var adminClient = new MetricsAdvisorAdministrationClient(new Uri(endpoint), new DefaultAzureCredential());

Concepts clés

MetricsAdvisorClient

MetricsAdvisorClient est l’interface d’interrogation principale pour les développeurs qui utilisent la bibliothèque cliente Metrics Advisor. Il fournit des méthodes synchrones et asynchrones pour accéder à une utilisation spécifique de Metrics Advisor, comme la liste des incidents, la récupération des causes racines des incidents et la récupération de données de série chronologique.

MetricsAdvisorAdministrationClient

MetricsAdvisorAdministrationClient est l’interface responsable de la gestion des entités dans la ressource Metrics Advisor. Il fournit des méthodes synchrones et asynchrones pour des tâches telles que la création et la mise à jour de flux de données, les configurations de détection d’anomalies et les configurations d’alerte d’anomalie.

Flux de données

Un DataFeed ingère régulièrement des tables de données agrégées à partir de votre source de données, comme CosmosDB ou un serveur SQL, et les rend disponibles pour le service Metrics Advisor. Il s’agit du point d’entrée des données et, par conséquent, du premier agent requis à définir avant que la détection d’anomalie puisse avoir lieu. Pour plus d’informations, consultez l’exemple Créer un flux de données à partir d’une source de données ci-dessous.

Métrique de flux de données

Une DataFeedMetric, ou simplement « métrique », est une mesure quantifiable utilisée pour surveiller une évaluation de la status d’un processus métier spécifique. Il peut s’agir du coût d’un produit au fil des mois, ou même d’une mesure quotidienne de la température. Le service surveillera la façon dont cette valeur varie au fil du temps à la recherche d’un comportement anormal. Un flux de données peut ingérer plusieurs métriques à partir de la même source de données.

Dimension de flux de données

Une DataFeedDimension, ou simplement « dimension », est une valeur catégorielle qui caractérise une métrique. Par instance, si une métrique représente le coût d’un produit, le type de produit (par exemple, chaussures, chapeaux) et la ville dans laquelle ces valeurs ont été mesurées (par exemple, New York, Tokyo) peuvent être utilisés comme dimension. La combinaison de plusieurs dimensions identifie une série chronologique univariée particulière.

Série chronologique

Une série chronologique est une séquence de points de données indexés chronologiquement. Ces points de données décrivent la variation de la valeur d’une métrique au fil du temps.

Avec une métrique, le service Metrics Advisor crée une série pour chaque combinaison possible de valeurs de dimension , ce qui signifie que plusieurs séries chronologiques peuvent être surveillées pour la même métrique.

Par exemple, supposons que les colonnes de données suivantes soient retournées par votre source de données :

City Category Coût Chiffre d’affaires
New York Chaussures 1045.00 1345.00
New York Chapeaux 670.00 502.00
Delhi Chaussures 991.00 1009.00
Delhi Chapeaux 623.00 711.00

Le coût et le revenu sont les métriques que le service doit surveiller, tandis que la ville et la catégorie sont les dimensions qui caractérisent ces métriques. Il existe 4 combinaisons de dimension possibles dans ces données :

  • Ville = New York, Catégorie = Chaussures
  • City = New York, Category = Hats
  • Ville = Delhi, Catégorie = Chaussures
  • Ville = Delhi, Catégorie = Chapeaux

Pour chaque métrique, le service crée 4 séries chronologiques pour surveiller les données, chacune représentant une combinaison de dimension possible. Chaque fois qu’une ingestion de source de données se produit, ces séries sont mises à jour avec un nouveau point de données, si disponible dans les données nouvellement ingérées.

Anomalie de point de données

Une DataPointAnomaly, ou simplement une « anomalie », se produit lorsqu’un point de données d’une série chronologique se comporte de manière inattendue. Cela peut se produire lorsqu’une valeur de point de données est trop élevée ou trop faible, ou lorsque sa valeur change brusquement entre les points de fermeture. Vous pouvez spécifier les conditions qu’un point de données doit remplir pour être considéré comme une anomalie avec un AnomalyDetectionConfiguration. Une fois l’ingestion de données effectuée, le service applique toutes les configurations existantes à l’ensemble de nouveaux points à la recherche d’anomalies. Pour plus d’informations, consultez l’exemple Créer une configuration de détection d’anomalie ci-dessous.

Incident d’anomalie

Quand des anomalies sont détectées sur plusieurs séries chronologiques au sein d’une métrique à un horodatage particulier, le service Metrics Advisor regroupe automatiquement les anomalies qui partagent la même cause racine en un seul AnomalyIncidentou simplement « incident ». Cela permettra d’éliminer considérablement l’effort de case activée chaque anomalie individuelle et de trouver rapidement le facteur contribuant le plus important à un problème.

Alerte d’anomalie

Une AnomalyAlert, ou simplement une « alerte », est déclenchée lorsqu’une anomalie détectée répond à un critère spécifié. Par instance, une alerte peut être déclenchée chaque fois qu’une anomalie avec une gravité élevée est détectée. Vous pouvez spécifier les conditions qu’une anomalie doit remplir pour déclencher une alerte avec un AnomalyAlertConfiguration. Une fois la détection d’anomalie effectuée sur les points de données nouvellement ingérés, le service applique toutes les configurations existantes aux nouvelles anomalies, et chaque configuration déclenche une alerte unique pour l’ensemble de points satisfaisant aux critères spécifiés. Les configurations d’alerte ne sont pas définies par défaut. Vous devez donc en créer une pour commencer à déclencher des alertes. Pour plus d’informations, consultez l’exemple Créer une configuration d’alerte d’anomalie ci-dessous.

Notification Hook

Un NotificationHook, ou simplement un « crochet », est un moyen de s’abonner aux notifications d’alerte . Vous pouvez passer un crochet à un et commencer à recevoir des AnomalyAlertConfiguration notifications pour chaque alerte qu’il crée. Pour plus d’informations, consultez l’exemple Créer un hook pour recevoir des alertes d’anomalie ci-dessous.

Sécurité des threads

Nous garantissons que toutes les méthodes de instance client sont sécurisées pour les threads et indépendantes les unes des autres (recommandations). Cela garantit que la recommandation de réutilisation des instances clientes est toujours sécurisée, même entre les threads.

Concepts supplémentaires

Options clientes | Accès à la réponse | Gestion des défaillances | Diagnostics | Moqueur | Durée de vie du client

Exemples

La section suivante fournit plusieurs extraits de code illustrant les modèles courants utilisés dans l’API .NET Metrics Advisor. Les extraits de code ci-dessous utilisent des appels de service asynchrones, mais notez que le package Azure.AI.MetricsAdvisor prend en charge les API synchrones et asynchrones.

Créer un flux de données à partir d’une source de données

Metrics Advisor prend en charge plusieurs types de sources de données. Dans cet exemple, nous allons montrer comment créer un DataFeed qui extrait des données d’un serveur SQL Server.

string sqlServerConnectionString = "<connectionString>";
string sqlServerQuery = "<query>";

var dataFeed = new DataFeed();

dataFeed.Name = "<dataFeedName>";
dataFeed.DataSource = new SqlServerDataFeedSource(sqlServerConnectionString, sqlServerQuery);
dataFeed.Granularity = new DataFeedGranularity(DataFeedGranularityType.Daily);

dataFeed.Schema = new DataFeedSchema();
dataFeed.Schema.MetricColumns.Add(new DataFeedMetric("cost"));
dataFeed.Schema.MetricColumns.Add(new DataFeedMetric("revenue"));
dataFeed.Schema.DimensionColumns.Add(new DataFeedDimension("category"));
dataFeed.Schema.DimensionColumns.Add(new DataFeedDimension("city"));

dataFeed.IngestionSettings = new DataFeedIngestionSettings(DateTimeOffset.Parse("2020-01-01T00:00:00Z"));

Response<DataFeed> response = await adminClient.CreateDataFeedAsync(dataFeed);

DataFeed createdDataFeed = response.Value;

Console.WriteLine($"Data feed ID: {createdDataFeed.Id}");
Console.WriteLine($"Data feed status: {createdDataFeed.Status.Value}");
Console.WriteLine($"Data feed created time: {createdDataFeed.CreatedOn.Value}");

Console.WriteLine($"Data feed administrators:");
foreach (string admin in createdDataFeed.Administrators)
{
    Console.WriteLine($" - {admin}");
}

Console.WriteLine($"Metric IDs:");
foreach (DataFeedMetric metric in createdDataFeed.Schema.MetricColumns)
{
    Console.WriteLine($" - {metric.Name}: {metric.Id}");
}

Console.WriteLine($"Dimensions:");
foreach (DataFeedDimension dimension in createdDataFeed.Schema.DimensionColumns)
{
    Console.WriteLine($" - {dimension.Name}");
}

Autres alternatives d’authentification de source de données

Certaines sources de données prennent en charge plusieurs types d’authentification. Par exemple, une chaîne de connexion, un principal de service et une SqlServerDataFeedSource identité managée. Vous pouvez case activée la liste complète des sources de données et leurs types d’authentification ici.

Une fois que vous vous êtes assuré que votre source de données prend en charge l’authentification que vous souhaitez utiliser, vous devez définir la propriété lors de la Authentication création ou de la mise à jour de la source de données :

var dataSoure = new SqlServerDataFeedSource("<connection-string>", "<query>")
{
    Authentication = SqlServerDataFeedSource.AuthenticationType.ManagedIdentity
};

N’oubliez pas que, à l’exception Basic des types d’authentification et ManagedIdentity , vous devez également avoir l’ID d’un correspondant DataSourceCredentialEntity dans le service. Pour créer une entité d’informations d’identification, vous devez effectuer les tâches suivantes :

string credentialName = "<credentialName>";

var credentialEntity = new ServicePrincipalCredentialEntity(credentialName, "<clientId>", "<clientSecret>", "<tenantId>");

Response<DataSourceCredentialEntity> response = await adminClient.CreateDataSourceCredentialAsync(credentialEntity);

DataSourceCredentialEntity createdCredentialEntity = response.Value;

Console.WriteLine($"Credential entity ID: {createdCredentialEntity.Id}");

Une fois que vous avez l’ID, ajoutez-le à la propriété lors de la DataSourceCredentialId configuration de votre source de données :

var dataSoure = new SqlServerDataFeedSource("<connection-string>", "<query>")
{
    Authentication = SqlServerDataFeedSource.AuthenticationType.ServicePrincipal,
    DataSourceCredentialId = "<credentialId>"
};

Vérifier le status d’ingestion d’un flux de données

Vérifiez le status d’ingestion d’un fichier créé DataFeedprécédemment.

string dataFeedId = "<dataFeedId>";

var startsOn = DateTimeOffset.Parse("2020-01-01T00:00:00Z");
var endsOn = DateTimeOffset.Parse("2020-09-09T00:00:00Z");
var options = new GetDataFeedIngestionStatusesOptions(startsOn, endsOn)
{
    MaxPageSize = 5
};

Console.WriteLine("Ingestion statuses:");
Console.WriteLine();

int statusCount = 0;

await foreach (DataFeedIngestionStatus ingestionStatus in adminClient.GetDataFeedIngestionStatusesAsync(dataFeedId, options))
{
    Console.WriteLine($"Timestamp: {ingestionStatus.Timestamp}");
    Console.WriteLine($"Status: {ingestionStatus.Status}");
    Console.WriteLine($"Service message: {ingestionStatus.Message}");
    Console.WriteLine();

    // Print at most 5 statuses.
    if (++statusCount >= 5)
    {
        break;
    }
}

Créer une configuration de détection d’anomalie

Créez un AnomalyDetectionConfiguration pour indiquer au service quels points de données doivent être considérés comme des anomalies.

string metricId = "<metricId>";
string configurationName = "<configurationName>";

var detectionConfiguration = new AnomalyDetectionConfiguration()
{
    MetricId = metricId,
    Name = configurationName,
    WholeSeriesDetectionConditions = new MetricWholeSeriesDetectionCondition()
};

var detectCondition = detectionConfiguration.WholeSeriesDetectionConditions;

var hardSuppress = new SuppressCondition(1, 100);
detectCondition.HardThresholdCondition = new HardThresholdCondition(AnomalyDetectorDirection.Down, hardSuppress)
{
    LowerBound = 5.0
};

var smartSuppress = new SuppressCondition(4, 50);
detectCondition.SmartDetectionCondition = new SmartDetectionCondition(10.0, AnomalyDetectorDirection.Up, smartSuppress);

detectCondition.ConditionOperator = DetectionConditionOperator.Or;

Response<AnomalyDetectionConfiguration> response = await adminClient.CreateDetectionConfigurationAsync(detectionConfiguration);

AnomalyDetectionConfiguration createdDetectionConfiguration = response.Value;

Console.WriteLine($"Anomaly detection configuration ID: {createdDetectionConfiguration.Id}");

Créer un hook pour recevoir des alertes d’anomalie

Metrics Advisor prend en charge les EmailNotificationHook classes et WebNotificationHook comme moyen de s’abonner aux notifications d’alerte . Dans cet exemple, nous allons montrer comment créer un EmailNotificationHook. Notez que vous devez passer le hook à une configuration d’alerte d’anomalie pour commencer à recevoir des notifications. Pour plus d’informations, consultez l’exemple Créer une configuration d’alerte d’anomalie ci-dessous.

string hookName = "<hookName>";

var emailHook = new EmailNotificationHook(hookName);

emailHook.EmailsToAlert.Add("email1@sample.com");
emailHook.EmailsToAlert.Add("email2@sample.com");

Response<NotificationHook> response = await adminClient.CreateHookAsync(emailHook);

NotificationHook createdHook = response.Value;

Console.WriteLine($"Hook ID: {createdHook.Id}");

Créer une configuration d’alerte d’anomalie

Créez un AnomalyAlertConfiguration pour indiquer au service quelles anomalies doivent déclencher des alertes.

string hookId = "<hookId>";
string anomalyDetectionConfigurationId = "<anomalyDetectionConfigurationId>";
string configurationName = "<configurationName>";

AnomalyAlertConfiguration alertConfiguration = new AnomalyAlertConfiguration()
{
    Name = configurationName
};

alertConfiguration.IdsOfHooksToAlert.Add(hookId);

var scope = MetricAnomalyAlertScope.CreateScopeForWholeSeries();
var metricAlertConfiguration = new MetricAlertConfiguration(anomalyDetectionConfigurationId, scope);

alertConfiguration.MetricAlertConfigurations.Add(metricAlertConfiguration);

Response<AnomalyAlertConfiguration> response = await adminClient.CreateAlertConfigurationAsync(alertConfiguration);

AnomalyAlertConfiguration createdAlertConfiguration = response.Value;

Console.WriteLine($"Alert configuration ID: {createdAlertConfiguration.Id}");

Requêtes détectées et alertes déclenchées

Examinez les alertes créées par une configuration d’alerte d’anomalie donnée.

string anomalyAlertConfigurationId = "<anomalyAlertConfigurationId>";

var startsOn = DateTimeOffset.Parse("2020-01-01T00:00:00Z");
var endsOn = DateTimeOffset.UtcNow;
var options = new GetAlertsOptions(startsOn, endsOn, AlertQueryTimeMode.AnomalyDetectedOn)
{
    MaxPageSize = 5
};

int alertCount = 0;

await foreach (AnomalyAlert alert in client.GetAlertsAsync(anomalyAlertConfigurationId, options))
{
    Console.WriteLine($"Alert created at: {alert.CreatedOn}");
    Console.WriteLine($"Alert at timestamp: {alert.Timestamp}");
    Console.WriteLine($"Id: {alert.Id}");
    Console.WriteLine();

    // Print at most 5 alerts.
    if (++alertCount >= 5)
    {
        break;
    }
}

Une fois que vous connaissez l’ID d’une alerte, listez les anomalies qui ont déclenché cette alerte.

string alertConfigurationId = "<alertConfigurationId>";
string alertId = "<alertId>";

var options = new GetAnomaliesForAlertOptions() { MaxPageSize = 3 };

int anomalyCount = 0;

await foreach (DataPointAnomaly anomaly in client.GetAnomaliesForAlertAsync(alertConfigurationId, alertId, options))
{
    Console.WriteLine($"Anomaly detection configuration ID: {anomaly.DetectionConfigurationId}");
    Console.WriteLine($"Data feed ID: {anomaly.DataFeedId}");
    Console.WriteLine($"Metric ID: {anomaly.MetricId}");
    Console.WriteLine($"Anomaly value: {anomaly.Value}");

    if (anomaly.ExpectedValue.HasValue)
    {
        Console.WriteLine($"Anomaly expected value: {anomaly.ExpectedValue}");
    }

    Console.WriteLine($"Anomaly at timestamp: {anomaly.Timestamp}");
    Console.WriteLine($"Anomaly detected at: {anomaly.CreatedOn}");
    Console.WriteLine($"Status: {anomaly.Status}");
    Console.WriteLine($"Severity: {anomaly.Severity}");
    Console.WriteLine("Series key:");

    foreach (KeyValuePair<string, string> dimension in anomaly.SeriesKey)
    {
        Console.WriteLine($"  Dimension '{dimension.Key}': {dimension.Value}");
    }

    Console.WriteLine();

    // Print at most 3 anomalies.
    if (++anomalyCount >= 3)
    {
        break;
    }
}

Dépannage

Général

Lorsque vous interagissez avec la bibliothèque cliente Cognitive Services Metrics Advisor à l’aide du Kit de développement logiciel (SDK) .NET, les erreurs retournées par le service entraînent un RequestFailedException avec le même code de status HTTP retourné par la demande d’API REST.

Par exemple, si vous essayez d’obtenir un flux de données à partir du service avec un ID inexistant, une 404 erreur est retournée, indiquant « Introuvable ».

string dataFeedId = "00000000-0000-0000-0000-000000000000";

try
{
    Response<DataFeed> response = await adminClient.GetDataFeedAsync(dataFeedId);
}
catch (RequestFailedException ex)
{
    Console.WriteLine(ex.ToString());
}

Notez que des informations supplémentaires sont enregistrées, telles que le message d’erreur retourné par le service.

Azure.RequestFailedException: Service request failed.
Status: 404 (Not Found)

Content:
{"code":"ERROR_INVALID_PARAMETER","message":"datafeedId is invalid."}

Headers:
X-Request-ID: REDACTED
x-envoy-upstream-service-time: REDACTED
apim-request-id: REDACTED
Strict-Transport-Security: REDACTED
X-Content-Type-Options: REDACTED
Date: Thu, 08 Oct 2020 09:04:31 GMT
Content-Length: 69
Content-Type: application/json; charset=utf-8

Configuration de la journalisation de la console

Le moyen le plus simple d’afficher les journaux consiste à activer la journalisation de console.

Pour créer un écouteur de journal du KIT de développement logiciel (SDK) Azure qui génère des messages dans la console, utilisez la AzureEventSourceListener.CreateConsoleLogger méthode .

// Set up a listener to monitor logged events.
using AzureEventSourceListener listener = AzureEventSourceListener.CreateConsoleLogger();

Pour en savoir plus sur d’autres mécanismes de journalisation, consultez Exemples de diagnostics.

Étapes suivantes

Des exemples montrant comment utiliser la bibliothèque Cognitive Services Metrics Advisor sont disponibles dans ce dépôt GitHub. Des exemples sont fournis pour chaque zone fonctionnelle main :

Contribution

Ce projet accepte les contributions et les suggestions. La plupart des contributions vous demandent d’accepter un contrat de licence de contribution (CLA) déclarant que vous avez le droit de nous accorder, et que vous nous accordez réellement, les droits d’utilisation de votre contribution. Pour plus d’informations, consultez cla.microsoft.com.

Quand vous envoyez une demande de tirage (pull request), un bot CLA détermine automatiquement si vous devez fournir un contrat CLA et agrémenter la demande de tirage de façon appropriée (par exemple, avec une étiquette ou un commentaire). Suivez simplement les instructions fournies par le bot. Vous ne devez effectuer cette opération qu’une seule fois sur tous les dépôts utilisant notre contrat CLA.

Ce projet a adopté le Code de conduite Open Source de Microsoft. Pour plus d’informations, consultez les Questions fréquentes (FAQ) sur le code de conduite ou envoyez vos questions ou vos commentaires à opencode@microsoft.com.