Учебник. Использование запросов Kusto

Лучший способ ознакомиться с языком запросов Kusto — просмотреть некоторые базовые запросы, чтобы лучше его понять. Рекомендуем использовать базу данных с примерами данных. Запросы, показанные в этом учебнике, должны выполняться в этой базе данных. Таблица StormEvents в примере базы данных содержит сведения о штормах, которые были в США.

Считать строки

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

Примечание по синтаксису. Запрос — это источник данных (обычно имя таблицы), за которым может следовать одна или несколько пар символа вертикальной черты и табличного оператора.

StormEvents | count

Выходные данные будут выглядеть следующим образом.

Count
59066

Дополнительные сведения см. в статье Оператор count.

Выбор подмножества столбцов с помощью оператора project

С помощью оператора project можно выбрать только нужные столбцы. См. следующий пример, в котором используются такие операторы, как project и take.

Фильтрация по логическому выражению с помощью оператора where

Давайте просмотрим только события flood в California за февраль 2007 г.:

StormEvents
| where StartTime > datetime(2007-02-01) and StartTime < datetime(2007-03-01)
| where EventType == 'Flood' and State == 'CALIFORNIA'
| project StartTime, EndTime , State , EventType , EpisodeNarrative

Выходные данные будут выглядеть следующим образом.

StartTime EndTime Состояние EventType EpisodeNarrative
2007-02-19 00:00:00.0000000 2007-02-19 08:00:00.0000000 Калифорния Наводнение Фронтальная система, перемещающаяся через южную область долины Сан-Хоакин, принесла кратковременный сильный ливневый дождь в западную часть округа Керн ранним утром 19 числа. Сообщалось о незначительном наводнении вдоль внутриштатного шоссе 166 около Тафта.

Отображение n строк с помощью оператора take

Давайте взглянем на некоторые данные. Что такое случайная выборка из пяти строк?

StormEvents
| take 5
| project  StartTime, EndTime, EventType, State, EventNarrative  

Выходные данные будут выглядеть следующим образом.

StartTime EndTime EventType Состояние Описание события (EventNarrative)
2007-09-18 20:00:00.0000000 2007-09-19 18:00:00.0000000 Сильный ливень Флорида За 24 часа в прибрежных районах округа Волуша выпало целых 9 дюймов осадков.
2007-09-20 21:57:00.0000000 2007-09-20 22:05:00.0000000 Ураган Флорида Ураган нагрянул в город Юстис в северном конце западного Крукед Лейк. Ураган быстро усилился до класса EF1, перемещаясь на северо-северо-запад через Юстис. Длина его пути составляла чуть меньше двух миль, а максимальная ширина — 300 ярдов. Ураган разрушил 7 домов. Двадцать семь домов получили серьезные повреждения, а 81 дом — незначительные. Серьезных травм не было, материальный ущерб составил 6,2 млн долларов США.
2007-09-29 08:11:00.0000000 2007-09-29 08:11:00.0000000 Торнадо ЮЖНО-АТЛАНТИЧЕСКИЕ ШТАТЫ Торнадо образовался в Атлантическом океане к юго-востоку от Мелборн-Бич и быстро приблизился к берегу.
2007-12-20 07:50:00.0000000 2007-12-20 07:53:00.0000000 Шквалистый ветер Миссисипи Было повалено множество больших деревьев, некоторые из них упали на линии электропередач. Повреждения затронули восточную часть округа Адамс.
2007-12-30 16:00:00.0000000 2007-12-30 16:05:00.0000000 Шквалистый ветер Грузия По сообщениям диспетчера округа несколько деревьев были повалены ветром вдоль Квинси Баттен Луп возле дороги внутриштатной автодорожной сети 206. Были подсчитаны расходы на уборку деревьев.

Но выводит строки из таблицы без определенного порядка, поэтому давайте отсортовать их. (limit является псевдонимом для оператора take и дает такой же результат.)

Упорядочение результатов с помощью операторов sort и top

  • Примечание по синтаксису. У некоторых операторов есть параметры, которые представлены в виде ключевых слов, таких как by.
  • В следующем примере desc упорядочивает результаты по убыванию, а asc — по возрастанию.

Показать первые n строк, упорядоченных по одному из столбцов:

StormEvents
| top 5 by StartTime desc
| project  StartTime, EndTime, EventType, State, EventNarrative  

Выходные данные будут выглядеть следующим образом.

StartTime EndTime EventType Состояние Описание события (EventNarrative)
2007-12-31 22:30:00.0000000 2007-12-31 23:59:00.0000000 Метель Мичиган Этот сильный снегопад продолжался до раннего утра Нового года.
2007-12-31 22:30:00.0000000 2007-12-31 23:59:00.0000000 Метель Мичиган Этот сильный снегопад продолжался до раннего утра Нового года.
2007-12-31 22:30:00.0000000 2007-12-31 23:59:00.0000000 Метель Мичиган Этот сильный снегопад продолжался до раннего утра Нового года.
2007-12-31 23:53:00.0000000 2007-12-31 23:53:00.0000000 Очень сильный ветер Калифорния Сообщалось о порывах ветра с севера на северо-восток со скоростью около 58 миль/ч в горах округа Вентура.
2007-12-31 23:53:00.0000000 2007-12-31 23:53:00.0000000 Очень сильный ветер Калифорния Датчик метеорологической станции в Уорм-Спрингс зафиксировал порывы северного ветра до 58 миль/ч.

Те же результаты можно получить, используя оператор sort, а затем take:

StormEvents
| sort by StartTime desc
| take 5
| project  StartTime, EndTime, EventType, EventNarrative

Вычисление производных столбцов с помощью оператора extend

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

StormEvents
| limit 5
| extend Duration = EndTime - StartTime 
| project StartTime, EndTime, Duration, EventType, State

Выходные данные будут выглядеть следующим образом.

StartTime EndTime Длительность EventType Состояние
2007-09-18 20:00:00.0000000 2007-09-19 18:00:00.0000000 22:00:00 Сильный ливень Флорида
2007-09-20 21:57:00.0000000 2007-09-20 22:05:00.0000000 00:08:00 Ураган Флорида
2007-09-29 08:11:00.0000000 2007-09-29 08:11:00.0000000 00:00:00 Торнадо ЮЖНО-АТЛАНТИЧЕСКИЕ ШТАТЫ
2007-12-20 07:50:00.0000000 2007-12-20 07:53:00.0000000 00:03:00 Шквалистый ветер Миссисипи
2007-12-30 16:00:00.0000000 2007-12-30 16:05:00.0000000 00:05:00 Шквалистый ветер Грузия

Вы можете повторно использовать имя столбца и присвоить ему результаты вычисления.

Пример.

print x=1
| extend x = x + 1, y = x
| extend x = x + 1

Выходные данные будут выглядеть следующим образом.

x y
3 1

Скалярные выражения могут включать в себя все обычные операторы (+, -, *, /, %) и ряд полезных функций.

Агрегирование групп строк с помощью оператора summarize

Подсчитайте количество событий для каждого штата:

StormEvents
| summarize event_count = count() by State

Оператор summarize группирует строки, имеющие одинаковые значения, в предложении by, а затем использует статистическую функцию (например, count) для объединения каждой группы в одну строку. В этом случае у нас есть по одной строке для каждого штата и столбец с количеством строк в этом штате.

Доступен ряд статистических функций. Вы можете использовать некоторые статистические функции в одном операторе summarize для получения нескольких вычисляемых столбцов. Например, можно получить количество штормов в каждом штате, а также общее количество уникальных типов штормов для каждого штата. Затем можно использовать оператор top, чтобы получить сведения о штатах, наиболее пострадавших от штормов:

StormEvents 
| summarize StormCount = count(), TypeOfStorms = dcount(EventType) by State
| top 5 by StormCount desc

Выходные данные будут выглядеть следующим образом.

Состояние StormCount TypeOfStorms
Техас 4701 27
Канзас 3166 21
Айова 2337 19
Иллинойс 2022 23
Миссури 2016 20

В результатах оператора summarize:

  • каждому столбцу, присваивается имя в by;
  • каждое вычисляемое выражение имеет столбец;
  • каждое сочетания значений by имеет строку.

Суммирование по скалярным значениям

В предложении by можно использовать скалярные значения (числовые, временные или интервалы), но их необходимо поместить в ячейки с помощью функции bin():

StormEvents
| where StartTime > datetime(2007-02-14) and StartTime < datetime(2007-02-21)
| summarize event_count = count() by bin(StartTime, 1d)

Запрос уменьшает все метки времени до интервала в один день:

StartTime event_count
2007-02-14 00:00:00.0000000 180
2007-02-15 00:00:00.0000000 66
2007-02-16 00:00:00.0000000 164
2007-02-17 00:00:00.0000000 103
2007-02-18 00:00:00.0000000 22
2007-02-19 00:00:00.0000000 52
2007-02-20 00:00:00.0000000 60

Функция bin () аналогична функции floor() на различных языках. Она просто уменьшает каждое значение до ближайшего кратного указанного остатка, чтобы оператор summarize мог назначить строки группам.

Отображение диаграммы или таблицы с помощью оператора render

Вы можете проецировать два столбца и использовать их в качестве осей X и Y диаграммы:

StormEvents 
| summarize event_count=count(), mid = avg(BeginLat) by State 
| sort by mid
| where event_count > 1800
| project State, event_count
| render columnchart

Снимок экрана: гистограмма с количеством штормов по штату.

Хотя мы удалили элемент mid в операции project, он нам еще пригодится, если мы хотим, чтобы штаты на диаграмме отображались именно в таком порядке.

Строго говоря, render — это клиентская функция, а не часть языка запросов. Тем не менее, она интегрирована в язык и полезна для представления результатов.

Временные диаграммы

Возвращаясь к числовым ячейкам, давайте отобразим временные ряды:

StormEvents
| summarize event_count=count() by bin(StartTime, 1d)
| render timechart

Снимок экрана: график событий, сегментированных по времени.

Множественные серии

Используйте несколько значений в предложении summarize by , чтобы создать отдельную строку для каждого сочетания значений.

StormEvents 
| where StartTime > datetime(2007-06-04) and StartTime < datetime(2007-06-10) 
| where Source in ("Source","Public","Emergency Manager","Trained Spotter","Law Enforcement")
| summarize count() by bin(StartTime, 10h), Source

Снимок экрана: подсчет событий в таблице с разбивкой по источнику.

Просто добавьте термин render к предыдущему примеру: | render timechart.

Снимок экрана: подсчет событий на графике с разбивкой по источнику.

Обратите внимание, что render timechart использует первый столбец в качестве оси X, а затем отображает другие столбцы в виде отдельных линий.

Ежедневный средний цикл

Как изменяется активность в течение обычного дня?

Количество событий в зависимости от времени по модулю в один день, сгруппированное по часам. Здесь вместо значения bin используется floor:

StormEvents
| extend hour = floor(StartTime % 1d , 1h)
| summarize event_count=count() by hour
| sort by hour asc
| render timechart

Снимок экрана: подсчет событий на временной диаграмме с разбивкой по часам.

В настоящее время render не устанавливает должным образом метки для продолжительности, но вместо этого можно использовать | render columnchart:

Снимок экрана: подсчет на гистограмме с разбивкой по часам.

Сравнение серий для нескольких дней

Как изменяется активность в течение дня в различных штатах?

StormEvents
| extend hour= floor( StartTime % 1d , 1h)
| where State in ("GULF OF MEXICO","MAINE","VIRGINIA","WISCONSIN","NORTH DAKOTA","NEW JERSEY","OREGON")
| summarize event_count=count() by hour, State
| render timechart

Снимок экрана: временная диаграмма с разбивкой по часам и штатам.

Выполните разделение на 1h, чтобы на оси X отображалось количество часов, а не длительность:

StormEvents
| extend hour= floor( StartTime % 1d , 1h)/ 1h
| where State in ("GULF OF MEXICO","MAINE","VIRGINIA","WISCONSIN","NORTH DAKOTA","NEW JERSEY","OREGON")
| summarize event_count=count() by hour, State
| render columnchart

Снимок экрана: гистограмма с разбивкой по часам и штатам.

Объединение типов данных

Как можно найти два конкретных типа события и штат, в котором они произошли?

Вы можете извлечь события, связанные со штормом, с помощью первого события EventType и второго события EventType, а затем объединить два набора в столбце State:

StormEvents
| where EventType == "Lightning"
| join (
    StormEvents 
    | where EventType == "Avalanche"
) on State  
| distinct State

Снимок экрана: объединение событий, связанных с молнией и лавиной.

Пример сеанса пользователя с использованием оператора join

В этом разделе не используется таблица StormEvents.

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

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

Вы можете использовать extend, чтобы указать псевдоним для двух меток времени, а затем вычислить длительность сеанса:

Events
| where eventName == "session_started"
| project start_time = timestamp, stop_time, country, session_id
| join ( Events
    | where eventName == "session_ended"
    | project stop_time = timestamp, session_id
    ) on session_id
| extend duration = stop_time - start_time
| project start_time, stop_time, country, duration
| take 10

Снимок экрана: таблица результатов для сеанса пользователя с расширением.

Рекомендуется использовать project, чтобы перед выполнением объединения выбрать только необходимые столбцы. В тех же предложениях переименуйте столбец timestamp.

Построение графика распределения

Возвращаясь к таблице StormEvents, какое количество штормов различной длительности существует?

StormEvents
| extend  duration = EndTime - StartTime
| where duration > 0s
| where duration < 3h
| summarize event_count = count()
    by bin(duration, 5m)
| sort by duration asc
| render timechart

Снимок экрана: временная диаграмма с количеством событий с разбивкой по продолжительности.

Вы также можете использовать | render columnchart:

Снимок экрана: гистограмма для временной диаграммы подсчета событий с разбивкой по продолжительности.

Процентили

Какие диапазоны длительности находятся в разных процентных долях штормов?

Чтобы получить эти сведения, используйте предыдущий запрос, но замените render следующим значением:

| summarize percentiles(duration, 5, 20, 50, 80, 95)

В этом случае мы не использовали предложение by, поэтому выходные данные представляют собой одну строку:

Снимок экрана: таблица результатов для суммирования процентилей с разбивкой по продолжительности.

На основе выходных данных можно определить следующее:

  • 5 % штормов имеют продолжительность менее 5 минут;
  • 50 % штормов длились менее одного часа и 25 минут;
  • 95 % штормов длились менее двух часов и 50 минут.

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

StormEvents
| extend  duration = EndTime - StartTime
| where duration > 0s
| where duration < 3h
| summarize event_count = count()
    by bin(duration, 5m), State
| sort by duration asc
| summarize percentiles(duration, 5, 20, 50, 80, 95) by State

Таблица со сводкой длительности процентилей с разбивкой по штатам.

Присвоение результата переменной с помощью оператора let

С помощью оператора let можно разделить части выражения запроса в предыдущем примере join. Результаты не изменились:

let LightningStorms = 
    StormEvents
    | where EventType == "Lightning";
let AvalancheStorms = 
    StormEvents
    | where EventType == "Avalanche";
LightningStorms 
| join (AvalancheStorms) on State
| distinct State

Совет

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

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

В следующем запросе таблица Logs должна находиться в базе данных по умолчанию:

Logs | where ...

Для доступа к таблице в другой базе данных используйте следующий синтаксис:

database("db").Table

Например, если имеются базы данных с именами Diagnostics и Telemetry и в них необходимо сопоставить некоторые данные, можно использовать следующий запрос (предполагается, что Diagnostics является базой данных по умолчанию):

Logs | join database("Telemetry").Metrics on Request MachineId | ...

Используйте этот запрос, если базой данных по умолчанию является Telemetry:

union Requests, database("Diagnostics").Logs | ...

В предыдущих двух запросах предполагается, что обе базы данных находятся в кластере, к которому вы подключены в данный момент. Если база данных Telemetry находилась в кластере с именем TelemetryCluster.kusto.windows.net, то для доступа к ней используйте следующий запрос:

Logs | join cluster("TelemetryCluster").database("Telemetry").Metrics on Request MachineId | ...

Примечание

Если указан кластер, то определение базы данных является обязательной.

Дополнительные сведения об объединении данных из нескольких баз данных в запросе см. в этой статье.

Дальнейшие действия

Лучший способ ознакомиться с языком запросов Kusto — просмотреть некоторые базовые запросы, чтобы лучше его понять. Эти запросы аналогичны запросам, которые используются в учебнике по Azure Data Explorer, однако в них используются данные из общих таблиц в рабочей области Azure Log Analytics.

Выполните эти запросы с помощью службы Log Analytics на портале Azure. Log Analytics — это средство, которое можно использовать для написания запросов журнала. Используйте данные журнала в Azure Monitor, а затем оцените результаты запроса журнала. Если вы не знакомы с Log Analytics, просмотрите учебник по Log Analytics.

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

Считать строки

Таблица InsightsMetrics содержит данные производительности, собираемые службами аналитики, такими как Azure Monitor для виртуальных машин и Azure Monitor для контейнеров. Чтобы узнать размер таблицы, мы передаем ее содержимое в оператор, который просто подсчитывает строки.

Запрос — это источник данных (обычно имя таблицы), за которым может следовать одна или несколько пар символа вертикальной черты и табличного оператора. В этом случае возвращаются все записи из таблицы InsightsMetrics, а затем отправляются оператору count. Оператор count отображает результаты, так как он является последней командой в запросе.

InsightsMetrics | count

Выходные данные будут выглядеть следующим образом.

Count
1 263 191

Фильтрация по логическому выражению с помощью оператора where

Таблица AzureActivity содержит записи из журнала действий Azure с аналитическими сведениями о событиях на уровне подписки или на уровне группы управления, которые произошли в Azure. Давайте рассмотрим только записи Critical за определенную неделю.

Оператор where является общепринятым в языке запросов Kusto. where фильтрует таблицу по строкам, соответствующим указанным условиям. В следующем примере используется несколько команд. Сначала, запрос извлекает все записи для таблицы. Затем фильтрует эти данные только по записям, которые соответствуют диапазону времени. Наконец, он фильтрует эти результаты только по записям, которые имеют уровень Critical.

Примечание

Помимо указания фильтра с помощью столбца TimeGenerated в запросе можно указать диапазон времени в Log Analytics. Подробные сведения см. в статье Область запросов журнала и временной диапазон в Azure Monitor Log Analytics.

AzureActivity
| where TimeGenerated > datetime(10-01-2020) and TimeGenerated < datetime(10-07-2020)
| where Level == 'Critical'

Снимок экрана: результаты примера с оператором where.

Выбор подмножества столбцов с помощью оператора project

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

AzureActivity
| where TimeGenerated > datetime(10-01-2020) and TimeGenerated < datetime(10-07-2020)
| where Level == 'Critical'
| project TimeGenerated, Level, OperationNameValue, ResourceGroup, _ResourceId

Снимок экрана: результаты примера с оператором project.

Отображение n строк с помощью оператора take

NetworkMonitoring содержит данные мониторинга для виртуальных сетей Azure. Давайте воспользуемся оператором take и просмотрим десять случайных строк из этой таблицы. Оператор take показывает заданное количество строк из таблицы без упорядочения:

NetworkMonitoring
| take 10
| project TimeGenerated, Computer, SourceNetwork, DestinationNetwork, HighLatency, LowLatency

Снимок экрана: результаты примера с оператором take.

Упорядочение результатов с помощью операторов sort и top

Вместо случайных записей мы можем вернуть последние пять записей, отсортировав их сначала по времени:

NetworkMonitoring
| sort by TimeGenerated desc
| take 5
| project TimeGenerated, Computer, SourceNetwork, DestinationNetwork, HighLatency, LowLatency

Этот же результат можно получить, используя оператор top:

NetworkMonitoring
| top 5 by TimeGenerated desc
| project TimeGenerated, Computer, SourceNetwork, DestinationNetwork, HighLatency, LowLatency

Снимок экрана: результаты примера с оператором top.

Вычисление производных столбцов с помощью оператора extend

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

Таблица Perf содержит данные производительности, собранные с виртуальных машин, на которых выполняется агент Log Analytics.

Perf
| where ObjectName == "LogicalDisk" and CounterName == "Free Megabytes"
| project TimeGenerated, Computer, FreeMegabytes = CounterValue
| extend FreeGigabytes = FreeMegabytes / 1000

Снимок экрана: результаты примера с оператором extend.

Агрегирование групп строк с помощью оператора summarize

Оператор summarize группирует строки, имеющие одинаковые значения в предложении by. Затем для объединения каждой группы в одну строку он использует статистическую функцию, такую как count. Доступен ряд статистических функций. Вы можете использовать некоторые статистические функции в одном операторе summarize для получения нескольких вычисляемых столбцов.

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

SecurityEvent
| summarize count() by Computer, Level

Снимок экрана: результаты примера с оператором summarize count.

Суммирование по скалярным значениям

Вы можете выполнять статистическую обработку по скалярным значениям, таким как числа и значения времени, но для группирования строк в отдельные наборы данных следует использовать функцию bin(). Например, если агрегирование выполняется по TimeGenerated, вы получите строку почти для каждого значения времени. Используйте bin() для консолидации этих значений по часу или дню.

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

InsightsMetrics
| where Computer startswith "DC"
| where Namespace  == "Processor" and Name == "UtilizationPercentage"
| summarize avg(Val) by Computer, bin(TimeGenerated, 1h)

Снимок экрана: результаты примера с оператором avg.

Отображение диаграммы или таблицы с помощью оператора render

Оператор Render указывает, как преобразовывать выходные данные запроса для просмотра. По умолчанию Log Analytics преобразовывает выходные данные для просмотра в виде таблицы. После выполнения запроса можно выбрать разные стили диаграмм. Оператор render рекомендуется включить в запросы, в которых обычно предпочтительнее использовать определенный стиль диаграммы.

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

InsightsMetrics
| where Computer == "DC00.NA.contosohotels.com"
| where Namespace  == "Processor" and Name == "UtilizationPercentage"
| summarize avg(Val) by Computer, bin(TimeGenerated, 1h)
| render timechart

Снимок экрана: результаты примера с оператором render.

Использование нескольких рядов

Если используете несколько значений в предложении summarize by, то для каждого набора значений на диаграмме отображается отдельный ряд:

InsightsMetrics
| where Computer startswith "DC"
| where Namespace  == "Processor" and Name == "UtilizationPercentage"
| summarize avg(Val) by Computer, bin(TimeGenerated, 1h)
| render timechart

Снимок экрана: результаты примера с оператором render с несколькими рядами.

Объединение данных из двух таблиц

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

VMComputer — это таблица, которую Azure Monitor использует для виртуальных машин, чтобы хранить сведения о виртуальных машинах, которые он отслеживает. Таблица InsightsMetrics содержит данные производительности, собираемые с этих виртуальных машин. В таблице InsightsMetrics содержится значение доступной памяти (но не ее процент). Чтобы вычислить процент, требуются данные о физической памяти для каждой виртуальной машины. Это значение находится в таблице VMComputer.

В следующем примере запроса для выполнения этого вычисления используется оператор join. Оператор distinct используется с VMComputer, так как сведения регулярно собираются с каждого компьютера. В результате для каждого компьютера в таблице создается несколько записей. Две таблицы объединяются с помощью столбца Computer. В результирующем наборе создается запись, которая включает столбцы из обеих таблиц для каждой записи в таблице InsightsMetrics со значением в столбце Computer, которое соответствует такому же значению в столбце Computer таблицы VMComputer.

VMComputer
| distinct Computer, PhysicalMemoryMB
| join kind=inner (
    InsightsMetrics
    | where Namespace == "Memory" and Name == "AvailableMB"
    | project TimeGenerated, Computer, AvailableMemoryMB = Val
) on Computer
| project TimeGenerated, Computer, PercentMemory = AvailableMemoryMB / PhysicalMemoryMB * 100

Снимок экрана: результаты примера с оператором join.

Присвоение результата переменной с помощью оператора let

Используйте оператор let, чтобы упростить чтение и управление запросами. Этот оператор можно использовать для присвоения результатов запроса переменной, которую можно использовать позднее. С помощью оператора let запрос в предыдущем примере можно переписать следующим образом:

let PhysicalComputer = VMComputer
    | distinct Computer, PhysicalMemoryMB;
let AvailableMemory = InsightsMetrics
    | where Namespace == "Memory" and Name == "AvailableMB"
    | project TimeGenerated, Computer, AvailableMemoryMB = Val;
PhysicalComputer
| join kind=inner (AvailableMemory) on Computer
| project TimeGenerated, Computer, PercentMemory = AvailableMemoryMB / PhysicalMemoryMB * 100

Снимок экрана: результаты примера с оператором let.

Дальнейшие действия