Анализ использования в рабочей области Log Analytics

Затраты на Azure Monitor могут значительно различаться в зависимости от объема собираемых данных в рабочей области Log Analytics. Этот том влияет на набор решений, использующих рабочую область, и объем данных, собираемых каждым решением. В этой статье приводятся рекомендации по анализу собранных данных для управления затратами на прием данных. Это помогает определить причину более высокого уровня использования, чем ожидалось. Кроме того, вы можете прогнозировать затраты при мониторинге дополнительных ресурсов и настройке различных функций Azure Monitor.

Совет

Стратегии снижения затрат Azure Monitor см. в статье "Оптимизация затрат" и Azure Monitor.

Причины более высокого по сравнению с ожидаемым использованием

Каждая рабочая область Log Analytics оплачивается как отдельная служба и включается в счет за подписку Azure. Объем приема данных может быть значительным в зависимости от:

  • Набор аналитических сведений и служб, включенных и их конфигурации.
  • Количество и тип отслеживаемых ресурсов.
  • Объем данных, собранных из каждого отслеживаемого ресурса.

Неожиданное увеличение любого из этих факторов может привести к увеличению расходов на хранение данных. Остальная часть этой статьи содержит методы для обнаружения такой ситуации и последующего анализа собранных данных для выявления и устранения источника повышенного использования.

Отправка оповещения при высоком уровне сбора данных

Чтобы избежать непредвиденных счетов, вы должны заранее получать уведомления каждый раз, когда сталкиваетесь с чрезмерным использованием. Уведомление позволит устранить любые потенциальные аномалии до окончания периода выставления счетов.

Следующий пример — это правило генерации оповещений поиска по журналам, которое отправляет оповещение, если оплачиваемый объем данных в течение последних 24 часов был больше 50 ГБ. Измените параметр Логика оповещений, чтобы использовать другое пороговое значение в зависимости от ожидаемого объема использования в вашей среде. Вы также можете увеличить частоту проверки использования до нескольких раз в сутки, но это приведет к увеличению платы за создание правила генерации оповещений.

Параметр Значение
Область применения
Целевая область Выберите рабочую область Log Analytics.
Условие
Query Usage | where IsBillable | summarize DataGB = sum(Quantity / 1000)
Измерение Мера: DataGB
Тип агрегирования: Итог
Степень детализации агрегирования: 1 день
Логика оповещений Оператор: Больше
Пороговое значение: 50
Частота вычислений: 1 день
Действия Выберите или добавьте группу действий для получения уведомлений о превышении порогового значения.
Сведения
Важность Предупреждение
Имя правила генерации оповещений Оплачиваемый объем данных, превышающий 50 ГБ в сутки.

Анализ использования в Azure Monitor

Запустите анализ с помощью существующих средств в Azure Monitor. Эти средства не требуют настройки и часто могут предоставлять необходимые сведения с минимальными усилиями. Если вам нужен более глубокий анализ собранных данных, чем существующие функции Azure Monitor, используйте любой из следующих запросов журналов в Log Analytics.

Аналитика рабочей области Log Analytics

Рабочая область Log Analytics Аналитика позволяет быстро понять данные в рабочей области. Например, можно определить следующее:

  • Таблицы данных, которые получают наибольший объем данных в основной таблице.
  • Лучшие ресурсы, которые вносят вклад в данные.
  • Тенденция приема данных.

См. вкладку "Использование" для разбивки приема по решениям и таблицам. Эти сведения помогут быстро определить таблицы, которые способствуют массовой части объема данных. На вкладке также отображается тенденция сбора данных с течением времени. Вы можете определить, постоянно ли сбор данных постоянно увеличивается с течением времени или внезапно увеличивается в ответ на изменение конфигурации.

Выберите дополнительные запросы для предварительно созданных запросов, которые помогут вам более подробно понять шаблоны данных.

Использование и ожидаемые затраты

Диаграмма приема данных надиаграмму "Использование" и предполагаемые затраты для каждой рабочей области показывает общий объем отправленных данных и сколько отправляется каждым решением за предыдущие 31 дней. Эта информация помогает определить тенденции, такие как увеличение общего использования данных или использования определенным решением.

Запрос томов данных из таблицы "Использование"

Анализ объема оплачиваемых данных, собранных определенной службой или решением. Эти запросы используют таблицу "Потребление", которая собирает данные о потреблении для каждой таблицы в рабочей области.

Примечание.

Предложение с TimeGenerated предназначено только для того, чтобы убедиться, что на портале Azure запрос выполняет ретроспективный поиск по умолчанию за 24 часа. При использовании типа StartTime данных "Использование" и EndTime представления сегментов времени, для которых отображаются результаты.

Оплачиваемый объем данных по типу за последний месяц

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

Оплачиваемый объем данных по решению и типу за последний месяц

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

Запрос тома данных непосредственно из событий

Вы можете использовать запросы журналов в Log Analytics, если требуется более глубокий анализ собранных данных. Каждая таблица в рабочей области Log Analytics содержит следующие стандартные столбцы, которые помогают анализировать оплачиваемые данные:

  • _IsBillable определяет записи, для которых взимается плата за прием. Используйте этот столбец для фильтрации неоплачиваемых данных.
  • _BilledSize предоставляет размер записи в байтах.

Объем данных с выставлением счетов для определенных событий

Если вы обнаружите, что определенный тип данных собирает чрезмерные данные, может потребоваться проанализировать данные в этой таблице, чтобы определить определенные записи, увеличивающиеся. В этом примере фильтруются идентификаторы определенных событий в Event таблице, а затем предоставляется число для каждого идентификатора. Этот запрос можно изменить с помощью столбцов из других таблиц.

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)

Объем данных по ресурсам, группам ресурсов или подпискам Azure

Вы можете проанализировать объем оплачиваемых данных, собранных из определенного ресурса или набора ресурсов. Эти запросы используют столбцы _ResourceId и _SubscriptionId для данных из ресурсов, размещенных в Azure.

Предупреждение

Используйте эти запросы поиска только в случае необходимости, так как сканирование по типам данных требует больших затрат ресурсов на выполнение. Если вам не нужны результаты для каждой подписки, группы ресурсов или имени ресурса, используйте таблицу "Использование ", как в предыдущих запросах.

Объем оплачиваемых данных с разбивкой по ИД ресурса за последний полный день

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

Объем оплачиваемых данных с разбивкой по группа ресурсов за последний полный день

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

Это может быть полезно для синтаксического анализа _ResourceId:

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

Объем оплачиваемых данных с разбивкой по подпискам за последний полный день

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

Совет

Для рабочих областей с большими объемами данных, выполняя такие запросы, как те, которые показаны в этом разделе, которые запрашивают большие объемы необработанных данных, может потребоваться ограничиться одним днем. Чтобы отслеживать тенденции с течением времени, рекомендуется настроить отчет Power BI и использовать добавочное обновление для сбора томов данных на ресурс один раз в день.

Объем данных на компьютер

Вы можете проанализировать объем оплачиваемых данных, собранных из виртуальной машины или набора виртуальных машин. Таблица "Использование" не имеет детализации для отображения томов данных для определенных виртуальных машин, поэтому эти запросы используют оператор поиска для поиска всех таблиц, включающих имя компьютера. Тип использования опущен, так как этот запрос предназначен только для аналитики тенденций данных.

Предупреждение

Используйте эти запросы поиска только в случае необходимости, так как сканирование по типам данных требует больших затрат ресурсов на выполнение. Если вам не нужны результаты для каждой подписки, группы ресурсов или имени ресурса, используйте таблицу "Использование ", как в предыдущих запросах.

Объем оплачиваемых данных с разбивкой по компьютерам за последний полный день

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

Количество оплачиваемых событий с разбивкой по компьютерам за последний полный день

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

Запрос томов данных, исключая известные типы данных

Следующий запрос возвращает ежемесячный объем данных в ГБ, исключая все типы данных, которые должны быть бесплатными от расходов на прием данных:

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

Чтобы искать данные, которые не могут правильно задать IsBillable (и которые могут привести к неправильному выставлению счетов или более конкретно под выставлением счетов), используйте этот запрос в рабочей области:

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

Запросы для общих типов данных

Если у вас есть чрезмерные оплачиваемые данные для определенного типа данных, может потребоваться выполнить запрос для анализа данных в этой таблице. Следующие запросы предоставляют примеры для некоторых распространенных типов данных:

Решение по безопасности

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

Решение для управления журналами

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

Тип данных Perf

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

Тип данных Event

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

Тип данных Syslog

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

Тип данных AzureDiagnostics

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

Данные Application Insights

Существует два подхода к изучению объема данных, собранных для Application Insights, в зависимости от того, есть используете ли вы классическое приложение или приложение на основе рабочей области. _BilledSize Используйте свойство, доступное для каждого события приема для рабочих областей и классических ресурсов. Вы также можете использовать агрегированные сведения в таблице systemEvents для классических ресурсов.

Примечание.

Запросы к таблицам приложений Аналитика, кроме тогоSystemEvents, будут работать как для ресурса на основе рабочей области, так и для классического Аналитика приложения. Обратная совместимость позволяет продолжать использовать устаревшие имена таблиц. Для ресурса на основе рабочей области откройте журналы в меню рабочей области Log Analytics. Для классического ресурса откройте журналы в меню "Приложение Аналитика".

Операции зависимости создают наибольший объем данных за последние 30 дней (на основе рабочей области или классический вариант)

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

Ежедневный объем данных по типу для этого ресурса Приложения Аналитика за последние 7 дней (только классическая версия)

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)  

Чтобы просмотреть тенденции тома данных для ресурсов приложения на основе рабочей области Аналитика, используйте запрос, содержащий все таблицы приложений Аналитика. В следующих запросах используются имена таблиц, относящиеся к ресурсам на основе рабочей области.

Ежедневный объем данных по типу для всех ресурсов приложения Аналитика в рабочей области в течение 7 дней

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)

Чтобы просмотреть тенденции тома данных только для одного ресурса приложения Аналитика, добавьте следующую строку перед summarize предыдущим запросом:

| where _ResourceId contains "<myAppInsightsResourceName>"

Совет

Для рабочих областей с большими объемами данных, выполняя такие запросы, как предыдущий, который запрашивает большие объемы необработанных данных, может потребоваться ограничиться одним днем. Чтобы отслеживать тенденции с течением времени, рекомендуется настроить отчет Power BI и использовать добавочное обновление для сбора томов данных на ресурс один раз в день.

Общие сведения о отправке данных узлами

Если у вас нет чрезмерных данных из какого-либо конкретного источника, возможно, у вас может быть чрезмерное количество агентов, отправляющих данные.

Количество узлов агента, которые отправляют пульс каждый день за последний месяц

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

Предупреждение

Используйте эти запросы поиска только в случае необходимости, так как сканирование по типам данных требует больших затрат ресурсов на выполнение. Если вам не нужны результаты для каждой подписки, группы ресурсов или имени ресурса, используйте таблицу "Использование ", как в предыдущих запросах.

Количество узлов, отправлявших любые данные за последние 24 часа

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

Объем данных, отправленный каждым узлом за последние 24 часа

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

Узлы, оплачиваемые по устаревшей ценовой категории "За узел"

Устаревшие счета за ценовую категорию для узлов с почасовой детализацией. Он также не учитывает узлы, которые отправляют только набор типов данных безопасности. Чтобы получить список компьютеров, которые будут выставляться как узлы, если рабочая область находится в устаревшей ценовой категории на узел, найдите узлы, которые отправляют выставленные счета типы данных, так как некоторые типы данных являются бесплатными. В этом случае используйте крайнее левое поле полного доменного имени.

Следующие запросы возвращают количество компьютеров с оплачиваемыми данными в час. Количество единиц в счете — это число "узел/мес.", представленное в запросе как billableNodeMonthsPerDay. Если в рабочей области установлено решение "Управление обновлениями", добавьте типы данных Update и UpdateSummary в список в пункте 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

Примечание.

Некоторая сложность в фактическом алгоритме выставления счетов при использовании целевого решения не представлена в предыдущем запросе.

Количество узлов безопасности и автоматизации

Количество отдельных узлов безопасности

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

Количество отдельных узлов автоматизации

 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

Данные, поступающие с задержкой

Если вы наблюдаете высокий прием данных, сообщаемый с помощью Usage записей, но вы не наблюдаете те же результаты, суммируя _BilledSize их непосредственно на типе данных, возможно, что у вас есть данные с опозданием. Эта ситуация возникает при приеме данных со старыми метками времени.

Например, у агента может возникнуть проблема с подключением и отправка накопленных данных при повторном подключении. Или узел может иметь неправильное время. Любой пример может привести к очевидному несоответствию между принятыми данными, сообщаемыми типом данных об использовании , и запросом, суммирующий _BilledSize по необработанным данным за определенный день, указанный TimeGenerated, метка времени при создании события.

Чтобы диагностировать проблемы с данными с задержкой, используйте столбец _TimeReceived и столбец TimeGenerated . Это _TimeReceived время, когда запись была получена точкой приема Azure Monitor в облаке Azure.

В следующем примере показано, как реагировать на объемы данных W3CIISLog с высоким уровнем приема данных 2 мая 2021 года, чтобы определить метки времени приема данных. Инструкция where TimeGenerated > datetime(1970-01-01) приведена только для того, чтобы указать пользовательскому интерфейсу Log Analytics просматривать все данные.

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 

Следующие шаги

  • См. статью Сведения о ценах на журналы Azure Monitor для получения сведений о способах вычисления расходов для данных в рабочей области Log Analytics и о различных вариантах конфигурации для целей сокращения расходов.
  • Сведения о различных типах расходов и способах их анализа в счете Azure Monitor приведены в статье Расходы и сведения об использовании в Azure Monitor.
  • Рекомендации по настройке затрат в Azure Monitor и управлению ими в целях минимизации расходов см. в статье "Рекомендации по управлению затратами в Azure Monitor".
  • Сведения об использовании преобразований сбора данных в Azure Monitor (предварительная версия) см. в статье об использовании преобразований, чтобы уменьшить объем данных, собранных в рабочей области Log Analytics, путем фильтрации нежелательных записей и столбцов.