Analisar o uso em um workspace do Log Analytics

Os custos do Azure Monitor podem variar significativamente com base no volume de dados que estão sendo coletados no workspace do Log Analytics. Esse volume é afetado pelo conjunto de soluções usando o workspace e a quantidade de dados coletados por cada solução. Este artigo fornece diretrizes sobre como analisar os dados coletados para ajudar a controlar os custos de ingestão de dados. Ele ajuda a determinar a causa do uso acima do esperado. Ele também ajuda você a prever os custos à medida que monitora mais recursos e configura diferentes recursos do Azure Monitor.

Dica

Para ver estratégias que reduzem os seus custos com o Azure Monitor, confira Otimização de custos e o Azure Monitor.

Causas para uso acima do esperado

Cada workspace do Log Analytics é cobrado como um serviço separado e contribui para a cobrança da sua assinatura do Azure. A quantidade de ingestão de dados pode ser considerável dependendo do seguinte:

  • Conjunto de insights e serviços habilitados e sua configuração.
  • O número e o tipo de recursos monitorados.
  • Volume de dados coletados de cada recurso monitorado.

Um aumento inesperado em qualquer um desses fatores pode resultar em aumento de encargos para retenção de dados. O restante deste artigo fornece métodos para detectar essa situação e, em seguida, analisar dados coletados para identificar e atenuar a origem do aumento do uso.

Enviar alertas quando a coleta de dados estiver alta

Para evitar cobranças inesperadas, você deve receber notificações proativas sempre que ocorrer uso excessivo. Isso permite resolver quaisquer anomalias em potencial antes do final do período de cobrança.

O exemplo a seguir é uma regra de alerta de pesquisa de log que envia um alerta se o volume de dados faturável ingerido nas últimas 24 horas for maior que 50 GB. Modifique a configuração da Lógica de Alerta para usar um limite diferente com base no uso esperado em seu ambiente. Você também pode aumentar a frequência para verificar o uso diversas vezes ao dia, mas isso resultará em uma cobrança mais alta pela regra de alerta.

Configuração Valor
Escopo
Escopo de destino Selecione seu espaço de trabalho do Log Analytics.
Condição
Consulta Usage | where IsBillable | summarize DataGB = sum(Quantity / 1000)
Medida Medida: DataGB
Tipo de agregação: Total
Granularidade de agregação: um dia
Lógica de alerta Operador: Maior que
Valor limite: 50
Frequência de avaliação: um dia
Ações Selecione ou adicione um grupo de ações para receber notificações quando o limite for excedido.
Detalhes
Severidade Aviso
Nome da regra de alerta Volume de dados faturável superior a 50 GB em 24 horas.

Análise de uso no Azure Monitor

Inicie sua análise com as ferramentas existentes no Azure Monitor. Essas ferramentas não exigem nenhuma configuração e geralmente podem fornecer as informações necessárias com o mínimo de esforço. Se você precisar de uma análise mais profunda dos dados coletados do que os recursos existentes do Azure Monitor, use qualquer uma das consultas de log no Log Analytics.

Insights do workspace do Log Analytics

O Insights do Workspace do Log Analytics fornece uma compreensão rápida dos dados em seu workspace. Por exemplo, você pode determinar:

  • Tabelas de dados que estão ingerindo o maior volume de dados na tabela principal.
  • Principais recursos que contribuem com dados.
  • Tendência de ingestão de dados.

Consulte a guia Uso para obter uma divisão da ingestão por solução e tabela. Essas informações podem ajudá-lo a identificar rapidamente as tabelas que contribuem para a maior parte do volume de dados. A guia também mostra a tendência da coleta de dados ao longo do tempo. Você pode determinar se a coleta de dados aumentou constantemente ao longo do tempo ou repentinamente em resposta a uma alteração de configuração.

Selecione Consultas adicionais para consultas pré-criadas que ajudam você a entender melhor seus padrões de dados.

Uso e custos estimados

A ingestão de dados por gráfico de solução na página Uso e custos estimados para cada workspace mostra o volume total de dados enviados e quanto está sendo enviado por cada solução nos últimos 31 dias. Essas informações ajudam você a determinar tendências como se qualquer aumento é proveniente do uso ou uso geral de dados por uma solução específica.

Consultando volumes de dados da tabela de Uso

Analise a quantidade de dados faturáveis coletados por um determinado serviço ou solução. Essas consultas usam a tabela Uso que coleta dados de uso para cada tabela no workspace.

Observação

A cláusula com TimeGenerated é usada apenas para garantir que a experiência de consulta no portal do Azure analise além do padrão de 24 horas. Ao usar o tipo de dados Uso, StartTime e EndTime representam os buckets de tempo para os quais os resultados são apresentados.

Volume de dados faturável por tipo no último mês

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 dados faturável por solução e tipo no último mês

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

Consultando o volume de dados diretamente dos eventos

Você pode usar consultas de log no Log Analytics se precisar de uma análise mais profunda dos dados coletados. Cada tabela em um workspace do Log Analytics tem as seguintes colunas padrão que podem ajudá-lo na análise de dados faturáveis:

  • _IsBillable identifica registros para os quais há uma carga de ingestão. Use esta coluna para filtrar dados não faturáveis.
  • _BilledSize fornece o tamanho em bytes do registro.

Volume de dados faturáveis de eventos específicos

Se você descobrir que um tipo de dados específico está coletando dados excessivos, talvez você queira analisar os dados nessa tabela para determinar registros específicos que estão aumentando. Este exemplo filtra as IDs de evento específicas na tabela Event e fornece uma contagem para cada ID. Você pode modificar essa consulta usando as colunas de outras tabelas.

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 dados por recurso do Azure, grupo de recursos ou assinatura

Você pode analisar a quantidade de dados faturáveis coletados de um determinado recurso ou conjunto de recursos. Essas consultas usam as colunas _ResourceId e _SubscriptionId para dados de recursos hospedados no Azure.

Aviso

Use essas consultas encontrar com moderação, pois verificações entre tipos de dados têm uma execução com uso intensivo de recursos. Se você não precisar de resultados por assinatura, grupo de recursos ou nome do recurso, use a tabela Uso como nas consultas acima.

Volume de dados faturável por ID do recurso para o último dia inteiro

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 dados faturável por grupo de recursos para o último dia inteiro

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

Pode ser útil analisar _ResourceId:

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

Volume de dados faturável por assinatura para o último dia inteiro

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

Dica

Para workspaces com grandes volumes de dados, poder ser que as consultas, como as mostradas nesta seção, que consulta grandes volumes de dados brutos, tenham que ser restritas a um dia. Para acompanhar tendências ao longo do tempo, considere configurar um relatório do Power BI e usar a atualização incremental para coletar volumes de dados por recurso uma vez por dia.

Volume de dados por computador

Você pode analisar a quantidade de dados faturáveis coletados de uma máquina virtual ou conjunto de máquinas virtuais. A tabela Uso não possui a granularidade para mostrar volumes de dados de máquinas virtuais específicas, portanto, essas consultas usam o operador de localização para pesquisar todas as tabelas que incluem um nome de computador. O tipo de Uso é omitido, pois essa consulta é apenas para análise de tendências de dados.

Aviso

Use essas consultas encontrar com moderação, pois verificações entre tipos de dados têm uma execução com uso intensivo de recursos. Se você não precisar de resultados por assinatura, grupo de recursos ou nome do recurso, use a tabela Uso como nas consultas acima.

Volume de dados faturável por computador para o último dia inteiro

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

Contagem de eventos faturáveis por computador para o último dia inteiro

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

Como consultar volumes de dados excluindo os tipos de dados gratuitos conhecidos

A seguinte consulta retornará o volume de dados mensal em GB, excluindo todos os tipos de dados que devem estar livres dos custos de ingestão de dados:

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

Para procurar dados que podem não ter IsBillable definido corretamente (e que podem resultar em cobrança incorreta, ou mais especificamente em cobrança), use esta consulta em seu workspace:

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

Consulta de tipos de dados comuns

Se você descobrir que tem dados faturáveis excessivos para um tipo de dados específico, talvez seja necessário executar uma consulta para analisar dados nessa tabela. As consultas a seguir fornecem exemplos para alguns tipos de dados comuns:

Solução de Segurança

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

Solução do Gerenciamento de log

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

Tipo de dados de Desempenho

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

Tipo de dados de Evento

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

Tipo de dados Syslog

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

Tipo de dados AzureDiagnostics

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

Dados do Application Insights

Há duas abordagens para investigar a quantidade de dados coletados para o Application Insights, dependendo se você tem um aplicativo clássico ou baseado em workspace. Use a propriedade _BilledSize que está disponível em cada evento ingerido para recursos clássicos e baseados no workspace. Você também pode usar informações agregadas na tabela systemEvents para recursos clássicos.

Observação

As consultas nas tabelas do Application Insights, exceto SystemEvents, funcionarão para um recurso do Application Insights baseado em workspace e clássico. A compatibilidade com versões anteriores permite que você continue usando nomes de tabela herdados. Para um recurso baseado em workspace, abra logs no menu do workspace do Log Analytics. Para um recurso clássico, abra logs no menu Application Insights.

As operações de dependência geram o maior volume de dados nos últimos 30 dias (baseado em workspace ou clássico)

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

Volume de dados diário por tipo para este recurso do Application Insights nos últimos sete dias (somente clássico)

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)  

Para examinar as tendências de volume de dados para recursos do Application Insights baseado em workspace, use uma consulta que inclui todas as tabelas do Application Insights. As consultas a seguir usam os nomes de tabela específicos para recursos baseados em workspace.

Volume de dados diário por tipo para todos os recursos do Application Insights em um workspace por sete dias

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)

Para examinar as tendências de volume de dados para apenas um recurso único do Application Insights, adicione a seguinte linha antes de summarize na consulta anterior:

| where _ResourceId contains "<myAppInsightsResourceName>"

Dica

Para workspaces com grandes volumes de dados, pode ser que a realização de consultas como a anterior – que consulta grandes volumes de dados brutos – tenham que ser restritas a um dia. Para acompanhar tendências ao longo do tempo, considere configurar um relatório do Power BI e usar a atualização incremental para coletar volumes de dados por recurso uma vez por dia.

Noções básicas sobre nós que enviam dados

Se você não tiver dados excessivos de nenhuma fonte específica, poderá ter um número excessivo de agentes que estão enviando dados.

Contagem de nós de agente que estão enviando uma pulsação todos os dias no último mês

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

Aviso

Use essas consultas encontrar com moderação, pois verificações entre tipos de dados têm uma execução com uso intensivo de recursos. Se você não precisar de resultados por assinatura, grupo de recursos ou nome do recurso, use a tabela Uso como nas consultas acima.

Contagem de nós que enviam dados nas últimas 24 horas

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

Volume de dados enviado por cada nó nas últimas 24 horas

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

Nós cobrados pelo tipo de preço herdado Por Nó

O tipo de preço Por Nó herdado cobra por nós com granularidade por hora. Ele também não conta os nós que estão enviando apenas um conjunto de tipos de dados de segurança. Para obter uma lista de computadores que serão cobrados como nós caso o workspace esteja no tipo de preço herdado Por Nó, procure os nós que estão enviando tipos de dados cobrados (alguns tipos de dados são gratuitos). Para isso, use o campo mais à esquerda do nome de domínio totalmente qualificado.

As consultas a seguir retornam a contagem de computadores com dados cobrados por hora. O número de unidades em sua fatura está em unidades de nó/meses, representado por billableNodeMonthsPerDay na consulta. Se o workspace tiver a solução Gerenciamento de Atualizações instalada, adicione os tipos de dados Update e UpdateSummary à lista na cláusula where da consulta acima.

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

Observação

Uma complexidade no algoritmo de cobrança real quando o direcionamento de solução usado não é representado na consulta anterior.

Contagens de nós de segurança e automação

Contagem de nós de segurança distintos

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

Número de nós de automação distintos

 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

Dados com chegada tardia

Se você observar alta ingestão de dados relatada usando os registros Usage, mas não observar os mesmos resultados somando _BilledSize diretamente ao tipo de dados, é possível que você tenha uma quantia significativa de dados de chegada tardia. Essa situação ocorre quando os dados são ingeridos com carimbos de data/hora antigos.

Por exemplo, um agente pode ter um problema de conectividade e enviar dados acumulados ao se reconectar. Ou um host pode ter um tempo incorreto. Qualquer exemplo pode vir a se manifestar por uma discrepância aparente entre os dados ingeridos relatados pelo tipo de dados de Uso, e uma consulta que soma _BilledSize aos dados brutos de um dia específico definido por TimeGenerated, o carimbo de data/hora de quando o evento foi gerado.

Para diagnosticar esses problemas, use a coluna _TimeReceived e a coluna TimeGenerated. A propriedade _TimeReceived é o momento em que o registro foi recebido pelo ponto de ingestão do Azure Monitor na nuvem do Azure.

O exemplo a seguir é uma resposta a grandes volumes de dados ingeridos de dados W3CIISLog em 2 de maio de 2021 para identificar os carimbos de data/hora nesses dados ingeridos. A instrução where TimeGenerated > datetime(1970-01-01) está presente apenas para fornecer à interface do usuário do Log Analytics a dica de procurar todos os dados.

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 

Próximas etapas