Analysez l’utilisation dans un espace de travail Log Analytics.

Les coûts d’Azure Monitor peuvent considérablement varier en fonction du volume de données collectées dans votre espace de travail Log Analytics. Ce volume est affecté par l’ensemble des solutions utilisant l’espace de travail et la quantité de données que chaque solution collecte. Cet article fournit des conseils sur l’analyse des données collectées afin de faciliter le contrôle des coûts d’ingestion des données. Il vous aide à déterminer la cause d’une utilisation plus élevée que prévu. Il vous aide également à prévoir vos coûts à mesure que vous surveillez davantage de ressources et que vous configurez différentes fonctionnalités d’Azure Monitor.

Conseil

Pour connaître les stratégies de réduction de vos coûts Azure Monitor, consultez Optimisation des coûts et Azure Monitor.

Causes d’une utilisation plus élevée que prévu

Chaque espace de travail Log Analytics est facturée en tant que service distinct et s’ajoute à la facture de votre abonnement Azure. La quantité de données ingérées peut être considérable en fonction de ce qui suit :

  • Ensemble d’insights et de services activés et configuration
  • Nombre et type de ressources surveillées
  • Volume de données collectées à partir de chaque ressource analysée

Une augmentation inattendue de ces facteurs peut entraîner une augmentation des frais de conservation des données. La suite de cet article fournit des méthodes permettant de détecter une telle situation, puis d’analyser les données collectées afin d’identifier et d’atténuer la source d’une utilisation accrue.

Envoyer une alerte lorsque la collecte de données est élevée

Pour une meilleure maîtrise de vos factures, vous devez être averti de manière proactive et à tout moment en cas d’utilisation excessive. Une notification vous permet de remédier à toute anomalie potentielle avant la fin de votre période de facturation.

L’exemple suivant est une règle d’alerte de recherche dans les journaux qui envoie une alerte si le volume de données facturables ingéré au cours des dernières 24 heures était supérieur à 50 Go. Modifiez le paramètre Logique d’alerte de manière à utiliser un seuil différent en fonction de l’utilisation attendue dans votre environnement. Vous pouvez également augmenter la fréquence de vérification de l’utilisation plusieurs fois par jour, mais cette opiton entraîne des frais plus élevés pour la règle d’alerte.

Paramètre Valeur
Étendue
Étendue cible Sélectionnez votre espace de travail Log Analytics.
Condition
Requête Usage | where IsBillable | summarize DataGB = sum(Quantity / 1000)
Mesure Mesure : DataGB
Type d’agrégation : Total
Granularité d’agrégation : 1 jour
Logique d'alerte Opérateur : Supérieur à
Valeur de seuil : 50
Fréquence d’évaluation : 1 jour
Actions Sélectionnez ou ajoutez un groupe d’actions à des fins d’avertissement lorsque le seuil est dépassé.
Détails
severity Avertissement
Nom de la règle d’alerte Volume de données facturables supérieur à 50 Go en 24 heures.

Analyse de l’utilisation dans Azure Monitor

Démarrez votre analyse avec des outils existants dans Azure Monitor. Ces outils ne nécessitent aucune configuration et peuvent souvent fournir les informations dont vous avez besoin avec un minimum d’effort. Si vous avez besoin d’une analyse plus approfondie des données collectées que celle proposée par les fonctionnalités Azure Monitor existantes, utilisez l’une des requêtes de journal suivantes dans Analytique des journaux d’activité.

Log Analytics Workspace Insights

Les insights de l’espace de travail Log Analytics Informations vous permettent de rapidement comprendre les données de votre espace de travail. Par exemple, vous pouvez déterminer les points suivants :

  • Les tables de données qui ingèrent le plus de volume de données dans la table principale.
  • Principales ressources contribuant aux données
  • Tendance d’ingestion des données

Reportez-vous à l’onglet Utilisation pour obtenir une répartition de l’ingestion par solution et par table. Cette information peut vous aider à identifier rapidement les tables qui contribuent à l’essentiel de votre volume de données. L’onglet affiche également les tendances de la collecte de données au fil du temps. Vous pouvez déterminer si la collecte de données a augmenté régulièrement au fil du temps ou si elle a soudainement augmenté en réponse à un changement de configuration.

Sélectionnez Requêtes supplémentaires pour les requêtes prédéfinies qui vous aident à mieux comprendre vos modèles de données.

Utilisation et estimation des coûts

Le graphique Ingestion de données par solution de la page Utilisation et estimation des coûts de chaque espace de travail montre le volume total des données envoyées et la quantité envoyée par chaque solution au cours des 31 derniers jours. Cette information vous permet de déterminer des tendances, par exemple, si une augmentation provient de l’utilisation globale des données ou de l’utilisation par une solution particulière.

Interrogation de volumes de données à partir de la table d’utilisation

Analysez la quantité de données facturables collectées par un service ou une solution spécifique. Ces requêtes utilisent la table Utilisation qui collecte les données d’utilisation pour chaque table de l’espace de travail.

Notes

La clause avec TimeGenerated permet uniquement de s’assurer que l’expérience de requête dans le portail Azure va au-delà des 24 heures par défaut. Quand vous utilisez le type de données Usage, StartTime et EndTime représentent la période pour laquelle les résultats sont présentés.

Volume de données facturables par type au cours du mois passé

Usage 
| where TimeGenerated > ago(32d)
| where StartTime >= startofday(ago(31d)) and EndTime < startofday(now())
| where IsBillable == true
| summarize BillableDataGB = sum(Quantity) / 1000. by bin(StartTime, 1d), DataType 
| render columnchart

Volume de données facturables par solution et par type au cours du mois passé

Usage 
| where TimeGenerated > ago(32d)
| where StartTime >= startofday(ago(31d)) and EndTime < startofday(now())
| where IsBillable == true
| summarize BillableDataGB = sum(Quantity) / 1000 by Solution, DataType
| sort by Solution asc, DataType asc

Interrogation directe du volume de données à partir des événements

Vous pouvez utiliser des requêtes de journal dans Log Analytics à des fins d’analyse plus approfondie des données collectées. Chaque table d’un espace de travail Log Analytics contient les colonnes standard suivantes susceptibles de vous aider à analyser les données facturables :

  • _IsBillable identifie les enregistrements entraînant des frais d’ingestion. Utilisez cette colonne pour filtrer les données non facturables.
  • _BilledSize indique la taille de l’enregistrement, en octets.

Volume de données facturables pour des événements spécifiques

Si vous constatez qu’un type de données particulier collecte des données excessives, vous pouvez analyser les données de cette table afin de déterminer les enregistrements qui augmentent. Cet exemple filtre les ID d’événements spécifiques dans la table Event, puis fournit un nombre pour chaque ID. Vous pouvez modifier cette requête à l’aide des colonnes d’autres tables.

Event
| where TimeGenerated > startofday(ago(31d)) and TimeGenerated < startofday(now()) 
| where EventID == 5145 or EventID == 5156
| where _IsBillable == true
| summarize count(), Bytes=sum(_BilledSize) by EventID, bin(TimeGenerated, 1d)

Volume de données par ressource Azure, groupe de ressources ou abonnement

Vous pouvez analyser la quantité de données facturables collectées à partir d’une ressource spécifique ou d’un ensemble de ressources. Ces requêtes utilisent les colonnes _ResourceId et _SubscriptionId pour les données des ressources hébergées dans Azure.

Avertissement

Utilisez les requêtes de recherche avec parcimonie, car les analyses exécutées sur différents types de données sont gourmandes en ressources. Si vous n’avez pas besoin de résultats par abonnement, groupe de ressources ou nom de ressource, utilisez la table Utilisation comme dans les requêtes précédentes.

Volume de données facturable par ID de ressource pour la dernière journée complète

find where TimeGenerated between(startofday(ago(1d))..startofday(now())) project _ResourceId, _BilledSize, _IsBillable
| where _IsBillable == true 
| summarize BillableDataBytes = sum(_BilledSize) by _ResourceId 
| sort by BillableDataBytes nulls last

Volume de données facturable par groupe de ressources pour la dernière journée complète

find where TimeGenerated between(startofday(ago(1d))..startofday(now())) project _ResourceId, _BilledSize, _IsBillable
| where _IsBillable == true 
| summarize BillableDataBytes = sum(_BilledSize) by _ResourceId
| extend resourceGroup = tostring(split(_ResourceId, "/")[4] )
| summarize BillableDataBytes = sum(BillableDataBytes) by resourceGroup 
| sort by BillableDataBytes nulls last

Il peut être utile d’analyser _ResourceId:

| parse tolower(_ResourceId) with "/subscriptions/" subscriptionId "/resourcegroups/" 
    resourceGroup "/providers/" provider "/" resourceType "/" resourceName   

Volume de données facturable par abonnement pour la dernière journée complète

find where TimeGenerated between(startofday(ago(1d))..startofday(now())) project _BilledSize, _IsBillable, _SubscriptionId
| where _IsBillable == true 
| summarize BillableDataBytes = sum(_BilledSize) by _SubscriptionId 
| sort by BillableDataBytes nulls last

Conseil

Pour les espaces de travail comportant de grands volumes de données, il peut être nécessaire de limiter à une seule journée l’exécution de requêtes telles que celles présentées dans cette section, qui interrogent de grands volumes de données brutes. Pour suivre les tendances au fil du temps, configurez un rapport Power BI et utilisez l’actualisation incrémentielle pour collecter des volumes de données par ressource une fois par jour.

Volume de données par ordinateur

Vous pouvez analyser la quantité de données facturables collectées à partir d’une machine virtuelle ou d’un ensemble de machines virtuelles. La table Utilisation n’a pas la granularité nécessaire pour présenter les volumes de données des machines virtuelles. Ces requêtes utilisent donc l’opérateur de recherche pour rechercher toutes les tables incluant un nom d’ordinateur. Le type Usage est omis car cette requête ne concerne que l’analyse des tendances des données.

Avertissement

Utilisez les requêtes de recherche avec parcimonie, car les analyses exécutées sur différents types de données sont gourmandes en ressources. Si vous n’avez pas besoin de résultats par abonnement, groupe de ressources ou nom de ressource, utilisez la table Utilisation comme dans les requêtes précédentes.

Volume de données facturable par ordinateur pour la dernière journée complète

find where TimeGenerated between(startofday(ago(1d))..startofday(now())) project _BilledSize, _IsBillable, Computer, Type
| where _IsBillable == true and Type != "Usage"
| extend computerName = tolower(tostring(split(Computer, '.')[0]))
| summarize BillableDataBytes = sum(_BilledSize) by  computerName 
| sort by BillableDataBytes desc nulls last

Nombre d’événements facturables par ordinateur pour la dernière journée complète

find where TimeGenerated between(startofday(ago(1d))..startofday(now())) project _IsBillable, Computer, Type
| where _IsBillable == true and Type != "Usage"
| extend computerName = tolower(tostring(split(Computer, '.')[0]))
| summarize eventCount = count() by computerName  
| sort by eventCount desc nulls last

Interrogation des volumes de données à l’exclusion des types de données gratuits connus

La requête suivante retourne le volume de données mensuel en Go, à l’exclusion de tous les types de données censés être exempts de frais d’ingestion de données :

let freeTables = dynamic([
"AppAvailabilityResults","AppSystemEvents","ApplicationInsights","AzureActivity","AzureNetworkAnalyticsIPDetails_CL",
"AzureNetworkAnalytics_CL","AzureTrafficAnalyticsInsights_CL","ComputerGroup","DefenderIoTRawEvent","Heartbeat",
"MAApplication","MAApplicationHealth","MAApplicationHealthIssues","MAApplicationInstance","MAApplicationInstanceReadiness",
"MAApplicationReadiness","MADeploymentPlan","MADevice","MADeviceNotEnrolled","MADeviceReadiness","MADriverInstanceReadiness",
"MADriverReadiness","MAProposedPilotDevices","MAWindowsBuildInfo","MAWindowsCurrencyAssessment",
"MAWindowsCurrencyAssessmentDailyCounts","MAWindowsDeploymentStatus","NTAIPDetails_CL","NTANetAnalytics_CL",
"OfficeActivity","Operation","SecurityAlert","SecurityIncident","UCClient","UCClientReadinessStatus",
"UCClientUpdateStatus","UCDOAggregatedStatus","UCDOStatus","UCDeviceAlert","UCServiceUpdateStatus","UCUpdateAlert",
"Usage","WUDOAggregatedStatus","WUDOStatus","WaaSDeploymentStatus","WaaSInsiderStatus","WaaSUpdateStatus"]);
Usage 
| where DataType !in (freeTables) 
| where TimeGenerated > ago(30d) 
| summarize MonthlyGB=sum(Quantity)/1000

Pour rechercher des données qui n’ont peut-être pas correctement défini IsBillable (et qui peuvent entraîner une facturation incorrecte, ou plus précisément une sous-facturation), utilisez cette requête sur votre espace de travail :

let freeTables = dynamic([
"AppAvailabilityResults","AppSystemEvents","ApplicationInsights","AzureActivity","AzureNetworkAnalyticsIPDetails_CL",
"AzureNetworkAnalytics_CL","AzureTrafficAnalyticsInsights_CL","ComputerGroup","DefenderIoTRawEvent","Heartbeat",
"MAApplication","MAApplicationHealth","MAApplicationHealthIssues","MAApplicationInstance","MAApplicationInstanceReadiness",
"MAApplicationReadiness","MADeploymentPlan","MADevice","MADeviceNotEnrolled","MADeviceReadiness","MADriverInstanceReadiness",
"MADriverReadiness","MAProposedPilotDevices","MAWindowsBuildInfo","MAWindowsCurrencyAssessment",
"MAWindowsCurrencyAssessmentDailyCounts","MAWindowsDeploymentStatus","NTAIPDetails_CL","NTANetAnalytics_CL",
"OfficeActivity","Operation","SecurityAlert","SecurityIncident","UCClient","UCClientReadinessStatus",
"UCClientUpdateStatus","UCDOAggregatedStatus","UCDOStatus","UCDeviceAlert","UCServiceUpdateStatus","UCUpdateAlert",
"Usage","WUDOAggregatedStatus","WUDOStatus","WaaSDeploymentStatus","WaaSInsiderStatus","WaaSUpdateStatus"]);
Usage 
| where DataType !in (freeTables) 
| where TimeGenerated > ago(30d) 
| where IsBillable == false 
| summarize MonthlyPotentialUnderbilledGB=sum(Quantity)/1000 by DataType

Interrogation de types de données courants

Si vous constatez que vous avez trop de données facturables pour un type de données particulier, vous devrez peut-être effectuer une requête pour analyser les données de cette table. Les requêtes suivantes fournissent des exemples pour certains types de données courants :

une solution de sécurité

SecurityEvent 
| summarize AggregatedValue = count() by EventID
| order by AggregatedValue desc nulls last

une solution de gestion des journaux

Usage 
| where Solution == "LogManagement" and iff(isnotnull(toint(IsBillable)), IsBillable == true, IsBillable == "true") == true 
| summarize AggregatedValue = count() by DataType
| order by AggregatedValue desc nulls last

le type de données Perf

Perf 
| summarize AggregatedValue = count() by CounterPath
Perf 
| summarize AggregatedValue = count() by CounterName

le type de données Event

Event 
| summarize AggregatedValue = count() by EventID
Event 
| summarize AggregatedValue = count() by EventLog, EventLevelName

le type de données Syslog

Syslog 
| summarize AggregatedValue = count() by Facility, SeverityLevel
Syslog 
| summarize AggregatedValue = count() by ProcessName

le type de données AzureDiagnostics

AzureDiagnostics 
| summarize AggregatedValue = count() by ResourceProvider, ResourceId

Données Application Insights

Deux approches permettent d’examiner la quantité de données collectées pour Application Insights, selon que vous disposez d’une application classique ou basée sur un espace de travail. Utilisez la _BilledSize propriété disponible sur chaque événement ingéré pour les ressources basées sur l’espace de travail et classiques. Vous pouvez également utiliser des informations agrégées dans la table systemEvents pour les ressources classiques.

Notes

Les requêtes sur les tables Application Insights, à l’exception de SystemEvents, fonctionnent à la fois pour une ressource Application Insights classique et basée sur un espace de travail. La compatibilité descendante vous permet de continuer à utiliser des noms de table hérités. Pour une ressource basée sur un espace de travail, ouvrez Journaux sur le menu Espace de travail Log Analytics. Pour une ressource classique, ouvrez Journaux sur le menu Application Insights.

Les opérations de dépendances génèrent le plus de volume de données au cours des 30 derniers jours (basé sur l’espace de travail ou classique)

dependencies
| where timestamp >= startofday(ago(30d))
| summarize sum(_BilledSize) by operation_Name
| render barchart  

Volume de données quotidien par type pour cette ressource Application Insights pour les sept derniers jours (classique uniquement)

systemEvents
| where timestamp >= startofday(ago(7d)) and timestamp < startofday(now())
| where type == "Billing"
| extend BillingTelemetryType = tostring(dimensions["BillingTelemetryType"])
| extend BillingTelemetrySizeInBytes = todouble(measurements["BillingTelemetrySize"])
| summarize sum(BillingTelemetrySizeInBytes) by BillingTelemetryType, bin(timestamp, 1d)  

Pour examiner les tendances du volume de données pour les ressources Application Insights basées sur l’espace de travail, utilisez une requête incluant toutes les tables Application Insights. Les requêtes suivantes utilisent les noms de la table spécifiques aux ressources basées sur l’espace de travail.

Volume de données quotidien par type pour toutes les ressources Application Insights d’un espace de travail au cours des sept derniers jours

union AppAvailabilityResults,
      AppBrowserTimings,
      AppDependencies,
      AppExceptions,
      AppEvents,
      AppMetrics,
      AppPageViews,
      AppPerformanceCounters,
      AppRequests,
      AppSystemEvents,
      AppTraces
| where TimeGenerated >= startofday(ago(7d)) and TimeGenerated < startofday(now())
| summarize sum(_BilledSize) by _ResourceId, bin(TimeGenerated, 1d)

Pour examiner les tendances de volume de données pour une ressource Application Insights unique, ajoutez la ligne suivante avant summarize dans la requête précédente :

| where _ResourceId contains "<myAppInsightsResourceName>"

Conseil

Pour les espaces de travail avec des volumes de données volumineux, l’exécution de requêtes telles que la précédente (qui interrogent de grands volumes de données brutes) peut devoir être limitée à un seul jour. Pour suivre les tendances au fil du temps, configurez un rapport Power BI et utilisez l’actualisation incrémentielle pour collecter des volumes de données par ressource une fois par jour.

Présentez des nœuds qui envoient des données.

En l’absence de données excessives provenant d’une source particulière, il est possible qu’un nombre excessif d’agents envoient des données.

Nombre de nœuds d’agent envoyant quotidiennement une pulsation au cours du mois passé

Heartbeat 
| where TimeGenerated > startofday(ago(31d))
| summarize nodes = dcount(Computer) by bin(TimeGenerated, 1d)    
| render timechart

Avertissement

Utilisez les requêtes de recherche avec parcimonie, car les analyses exécutées sur différents types de données sont gourmandes en ressources. Si vous n’avez pas besoin de résultats par abonnement, groupe de ressources ou nom de ressource, utilisez la table Utilisation comme dans les requêtes précédentes.

Nombre de nœuds envoyant des données au cours des 24 dernières heures

find where TimeGenerated > ago(24h) project Computer
| extend computerName = tolower(tostring(split(Computer, '.')[0]))
| where computerName != ""
| summarize nodes = dcount(computerName)

Volume de données envoyées par chaque nœud au cours des 24 dernières heures

find where TimeGenerated > ago(24h) project _BilledSize, Computer
| extend computerName = tolower(tostring(split(Computer, '.')[0]))
| where computerName != ""
| summarize TotalVolumeBytes=sum(_BilledSize) by computerName

Nœuds facturés par le niveau tarifaire hérité Par nœud

Le niveau tarifaire par nœud hérité facture les nœuds avec une granularité horaire. Il ne compte pas non plus les nœuds qui n’envoient qu’un ensemble de types de données de sécurité. Pour obtenir une liste des ordinateurs qui seront facturés en tant que nœuds si l’espace de travail se trouve au niveau tarifaire hérité Par nœud, recherchez les nœuds qui envoient des types de données facturés, parce que certains types de données étant gratuits. Dans ce cas, utilisez le champ tout à gauche du nom de domaine complet.

Les requêtes suivantes retournent le nombre d’ordinateurs avec des données facturées par heure. Le nombre d’unités sur votre facture est exprimé en unités nœuds par mois, ce qui est représenté par billableNodeMonthsPerDay dans la requête. Si la solution Update Management est installée sur l’espace de travail, ajoutez les types de données Update et UpdateSummary à la liste dans la clause where.

find where TimeGenerated >= startofday(ago(7d)) and TimeGenerated < startofday(now()) project Computer, _IsBillable, Type, TimeGenerated
| where Type !in ("SecurityAlert", "SecurityBaseline", "SecurityBaselineSummary", "SecurityDetection", "SecurityEvent", "WindowsFirewall", "MaliciousIPCommunication", "LinuxAuditLog", "SysmonEvent", "ProtectionStatus", "WindowsEvent")
| extend computerName = tolower(tostring(split(Computer, '.')[0]))
| where computerName != ""
| where _IsBillable == true
| summarize billableNodesPerHour=dcount(computerName) by bin(TimeGenerated, 1h)
| summarize billableNodesPerDay = sum(billableNodesPerHour)/24., billableNodeMonthsPerDay = sum(billableNodesPerHour)/24./31.  by day=bin(TimeGenerated, 1d)
| sort by day asc

Notes

Une certaine complexité dans l’algorithme de facturation réel lorsque le ciblage des solutions est utilisé n’est pas représentée dans la requête précédente.

Nombres de nœuds de sécurité et Automation

Nombre de nœuds de sécurité distincts

union
(
    Heartbeat
    | where (Solutions has 'security' or Solutions has 'antimalware' or Solutions has 'securitycenter')
    | project Computer
),
(
    ProtectionStatus
    | where Computer !in (Heartbeat | project Computer)
    | project Computer
)
| distinct Computer
| project lowComputer = tolower(Computer)
| distinct lowComputer
| count

Nombre de nœuds Automation distincts

 ConfigurationData 
 | where (ConfigDataType == "WindowsServices" or ConfigDataType == "Software" or ConfigDataType =="Daemons") 
 | extend lowComputer = tolower(Computer) | summarize by lowComputer 
 | join (
     Heartbeat 
       | where SCAgentChannel == "Direct"
       | extend lowComputer = tolower(Computer) | summarize by lowComputer, ComputerEnvironment
 ) on lowComputer
 | summarize count() by ComputerEnvironment | sort by ComputerEnvironment asc

Données arrivant en retard

Si vous observez une ingestion des données élevée signalée à l’aide des enregistrements Usage, mais que vous n’observez pas les mêmes résultats en additionnant _BilledSize directement sur le type de données, il est possible que vous ayez des données arrivées tardivement. Cette situation se produit lorsque des données sont ingérées avec des timestamps anciens.

Par exemple, un agent peut présenter un problème de connectivité et envoyer des données accumulées quand il se reconnecte. De même, un hôte peut afficher une heure incorrecte. Les deux exemples peuvent entraîner une divergence apparente entre les données ingérées signalées par le type de données Usage et une requête additionnant _BilledSize sur les données brutes pour un jour particulier spécifié par TimeGenerated, le timestamp au moment où l’événement a été généré.

Pour diagnostiquer les problèmes de données arrivant en retard, utilisez la colonne _TimeReceived et la colonne TimeGenerated. La propriété _TimeReceived correspond à l’heure de réception de l’enregistrement par le point d’ingestion Azure Monitor dans le cloud Azure.

L’exemple suivant répond à des volumes de élevés de données W3CIISLog ingérées le 2 mai 2021 pour identifier les timestamps sur ces données ingérées. L’instruction where TimeGenerated > datetime(1970-01-01) est incluse pour fournir un indice à l’interface utilisateur de Log Analytics pour l’examen de toutes les données.

W3CIISLog
| where TimeGenerated > datetime(1970-01-01)
| where _TimeReceived >= datetime(2021-05-02) and _TimeReceived < datetime(2021-05-03) 
| where _IsBillable == true
| summarize BillableDataMB = sum(_BilledSize)/1.E6 by bin(TimeGenerated, 1d)
| sort by TimeGenerated asc 

Étapes suivantes