Поделиться через


Запрос данных карты из VM Insights

Внимание

Агент зависимостей и интерфейс карты в VM Insights будут прекращены 30 июня 2028 года. Дополнительные сведения см. в руководстве по выходу на пенсию .

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

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

Замечание

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

Сопоставление записей

Одна запись создается в час для каждого уникального компьютера и процесса в дополнение к записям, создаваемым при запуске процесса или компьютерах или добавленных в VM Insights. Поля и значения таблицы VMComputer сопоставляются с полями ресурса компьютера в API Azure Resource Manager ServiceMap. Поля и значения в таблице VMProcess соответствуют полям ресурса Process в API Azure Resource Manager ServiceMap. Поле _ResourceId соответствует полю имени в соответствующем ресурсе Resource Manager.

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

  • Компьютер: используйте _ResourceId для уникальной идентификации компьютера в рабочей области Log Analytics.
  • Процесс. Используйте _ResourceId для уникальной идентификации процесса в рабочей области Log Analytics.

Так как для указанных процесса и компьютера в заданном диапазоне времени могут существовать несколько записей, то запросы могут возвращать несколько записей для одного и того же компьютера или процесса. Чтобы включить только самую последнюю запись, добавьте | summarize arg_max(TimeGenerated, *) by ResourceId к запросу.

Подключения и порты

VMConnection и VMBoundPort предоставляют сведения о подключениях для компьютера (входящего и исходящего трафика) и портах сервера, открытых или активных на них. Метрики подключения также предоставляются через API, которые предоставляют средства для получения определенной метрики во время периода времени. TCP-подключения, принятые на сокете прослушивания, являются входящими, а подключения, созданные путем подключения к заданному IP-адресу и порту, являются исходящими. Свойство Direction представляет направление соединения, для которого можно задать значение inbound или outbound.

Записи в этих таблицах создаются на основе данных, полученных программой Dependency Agent. Каждая запись соответствует наблюдению, выполняемому 1 раз в минуту. Свойство TimeGenerated указывает начало интервала времени. Каждая запись содержит сведения для идентификации соответствующей сущности, то есть подключения или порта, а также метрик, связанных с этой сущностью. На данный момент система собирает данные, касающиеся только действий в сети, связанных с протоколом TCP/IPv4.

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

Метрики

VMConnection и VMBoundPort включают данные метрик с информацией о томе данных, отправляемых и полученных при заданном логическом подключении или сетевом порту (BytesSent, BytesReceived). Также включается время отклика — это период, в течение которого вызывающий абонент ожидает обработки и реакции на запрос, отправленный через соединение удаленной конечной точкой (ResponseTimeMax, ResponseTimeMin, ResponseTimeSum). Полученное время отклика — это оценочное значение истинного времени отклика базового протокола приложений. Он вычисляется с помощью эвристики на основе наблюдения за потоком данных между источником и приемником физического сетевого подключения. Концептуально это разница между временем последнего байта запроса покидает отправителя и время, когда последний байт ответа возвращается к нему. Эти две метки времени используются для регистрации событий запроса и отклика для заданного физического подключения. Разность этих значений представляет собой время отклика для одного запроса.

Этот алгоритм представляет собой приближение, которое может работать с различной степенью успешности в зависимости от фактического протокола приложения, используемого для заданного сетевого подключения. Например, текущий подход хорошо подходит для протоколов на основе ответа на запросы, таких как HTTP(S), но не работает с односторонними протоколами на основе очереди сообщений.

Некоторые важные моменты, которые следует учитывать, включают:

  1. Если процесс принимает подключения по одному IP-адресу, но через несколько сетевых интерфейсов, сообщается отдельная запись для каждого интерфейса.
  2. Записи с подстановочными IP-адресами не содержат действий. Они включены для представления того, что порт на компьютере открыт для входящего трафика.
  3. Чтобы уменьшить многословие и объем данных, записи с подстановочными IP-адресами пропускаются, если существует соответствующая запись с конкретным IP-адресом для того же процесса, порта и протокола. Если IP-запись подстановочного знака отсутствует, свойство записи IsWildcardBind с указанным IP-адресом устанавливается на True, чтобы указать, что порт доступен через каждый интерфейс машины, создающей отчет.
  4. Порты, привязанные только к конкретному интерфейсу, имеют IsWildcardBind значение False.

Именование и классификация

Для удобства IP-адрес удалённой стороны подключения включается в RemoteIp свойство. Для входящих подключений RemoteIp совпадает с SourceIp, а для исходящих подключений - с DestinationIp. Свойство RemoteDnsCanonicalNames представляет DNS-канонические имена, которые сообщаются машиной для RemoteIp. Свойство RemoteDnsQuestions представляет DNS-вопросы, запрашиваемые компьютером для RemoteIp. Свойство RemoveClassification зарезервировано для использования в будущем.

Вредоносный IP-адрес

Каждое RemoteIpVMConnection свойство в таблице проверяется на набор IP-адресов с известным вредоносным действием. Если RemoteIp определяется как вредоносный объект, заполняются следующие свойства. Если IP-адрес не считается вредоносным, свойства пусты.

  • MaliciousIp
  • IndicatorThreadType
  • Description
  • TLPLevel
  • Confidence
  • Severity
  • FirstReportedDateTime
  • LastReportedDateTime
  • IsActive
  • ReportReferenceLink
  • AdditionalInformation

Примерные запросы к картам

Перечисление всех известных компьютеров

VMComputer | summarize arg_max(TimeGenerated, *) by _ResourceId

Когда виртуальная машина была в последний раз перезагружена

let Today = now(); VMComputer | extend DaysSinceBoot = Today - BootTime | summarize by Computer, DaysSinceBoot, BootTime | sort by BootTime asc

Сводка по виртуальным машинам Azure по образу, расположению и номеру SKU

VMComputer | where AzureLocation != "" | summarize by Computer, AzureImageOffering, AzureLocation, AzureImageSku

Перечисление емкости физической памяти всех управляемых компьютеров

VMComputer | summarize arg_max(TimeGenerated, *) by _ResourceId | project PhysicalMemoryMB, Computer

Перечисление имени компьютера, DNS, IP-адреса и ОС

VMComputer | summarize arg_max(TimeGenerated, *) by _ResourceId | project Computer, OperatingSystemFullName, DnsNames, Ipv4Addresses

Поиск всех процессов с помощью sql в командной строке

VMProcess | where CommandLine contains_cs "sql" | summarize arg_max(TimeGenerated, *) by _ResourceId

Поиск компьютера (последняя запись) по имени ресурса

search in (VMComputer) "m-4b9c93f9-bc37-46df-b43c-899ba829e07b" | summarize arg_max(TimeGenerated, *) by _ResourceId

Поиск компьютера (последняя запись) по IP-адресу

search in (VMComputer) "10.229.243.232" | summarize arg_max(TimeGenerated, *) by _ResourceId

Перечисление всех известных процессов на указанном компьютере

VMProcess | where Machine == "m-559dbcd8-3130-454d-8d1d-f624e57961bc" | summarize arg_max(TimeGenerated, *) by _ResourceId

Вывод списка всех компьютеров под управлением SQL Server

VMComputer | where AzureResourceName in ((search in (VMProcess) "*sql*" | distinct Machine)) | distinct Computer

Список всех уникальных версий продукта curl в моем центре обработки данных

VMProcess | where ExecutableName == "curl" | distinct ProductVersion

Тенденции отправки и получения байтов

VMConnection | summarize sum(BytesSent), sum(BytesReceived) by bin(TimeGenerated,1hr), Computer | order by Computer desc | render timechart

Какие виртуальные машины Azure передают больше всего байтов

VMConnection | join kind=fullouter(VMComputer) on $left.Computer == $right.Computer | summarize count(BytesSent) by Computer, AzureVMSize | sort by count_BytesSent desc

Тенденции состояния связи

VMConnection | where TimeGenerated >= ago(24hr) | where Computer == "acme-demo" | summarize dcount(LinksEstablished), dcount(LinksLive), dcount(LinksFailed), dcount(LinksTerminated) by bin(TimeGenerated, 1h) | render timechart

Тенденция сбоев подключения

VMConnection | where Computer == "acme-demo" | extend bythehour = datetime_part("hour", TimeGenerated) | project bythehour, LinksFailed | summarize failCount = count() by bythehour | sort by bythehour asc | render timechart

Привязанные порты

VMBoundPort
| where TimeGenerated >= ago(24hr)
| where Computer == 'admdemo-appsvr'
| distinct Port, ProcessName

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

VMBoundPort
| where Ip != "127.0.0.1"
| summarize by Computer, Machine, Port, Protocol
| summarize OpenPorts=count() by Computer, Machine
| order by OpenPorts desc

Оценка процессов в рабочей области по количеству открытых портов

VMBoundPort
| where Ip != "127.0.0.1"
| summarize by ProcessName, Port, Protocol
| summarize OpenPorts=count() by ProcessName
| order by OpenPorts desc

Статистическое поведение для каждого порта

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

VMBoundPort
| where Ip != "127.0.0.1"
| summarize BytesSent=sum(BytesSent), BytesReceived=sum(BytesReceived), LinksEstablished=sum(LinksEstablished), LinksTerminated=sum(LinksTerminated), arg_max(TimeGenerated, LinksLive) by Machine, Computer, ProcessName, Ip, Port, IsWildcardBind
| project-away TimeGenerated
| order by Machine, Computer, Port, Ip, ProcessName

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

// the machines of interest
let machines = datatable(m: string) ["m-82412a7a-6a32-45a9-a8d6-538354224a25"];
// map of ip to monitored machine in the environment
let ips=materialize(VMComputer
| summarize ips=makeset(todynamic(Ipv4Addresses)) by MonitoredMachine=AzureResourceName
| mvexpand ips to typeof(string));
// all connections to/from the machines of interest
let out=materialize(VMConnection
| where Machine in (machines)
| summarize arg_max(TimeGenerated, *) by ConnectionId);
// connections to localhost augmented with RemoteMachine
let local=out
| where RemoteIp startswith "127."
| project ConnectionId, Direction, Machine, Process, ProcessName, SourceIp, DestinationIp, DestinationPort, Protocol, RemoteIp, RemoteMachine=Machine;
// connections not to localhost augmented with RemoteMachine
let remote=materialize(out
| where RemoteIp !startswith "127."
| join kind=leftouter (ips) on $left.RemoteIp == $right.ips
| summarize by ConnectionId, Direction, Machine, Process, ProcessName, SourceIp, DestinationIp, DestinationPort, Protocol, RemoteIp, RemoteMachine=MonitoredMachine);
// the remote machines to/from which we have connections
let remoteMachines = remote | summarize by RemoteMachine;
// all augmented connections
(local)
| union (remote)
//Take all outbound records but only inbound records that come from either //unmonitored machines or monitored machines not in the set for which we are computing dependencies.
| where Direction == 'outbound' or (Direction == 'inbound' and RemoteMachine !in (machines))
| summarize by ConnectionId, Direction, Machine, Process, ProcessName, SourceIp, DestinationIp, DestinationPort, Protocol, RemoteIp, RemoteMachine
// identify the remote port
| extend RemotePort=iff(Direction == 'outbound', DestinationPort, 0)
// construct the join key we'll use to find a matching port
| extend JoinKey=strcat_delim(':', RemoteMachine, RemoteIp, RemotePort, Protocol)
// find a matching port
| join kind=leftouter (VMBoundPort 
| where Machine in (remoteMachines) 
| summarize arg_max(TimeGenerated, *) by PortId 
| extend JoinKey=strcat_delim(':', Machine, Ip, Port, Protocol)) on JoinKey
// aggregate the remote information
| summarize Remote=makeset(iff(isempty(RemoteMachine), todynamic('{}'), pack('Machine', RemoteMachine, 'Process', Process1, 'ProcessName', ProcessName1))) by ConnectionId, Direction, Machine, Process, ProcessName, SourceIp, DestinationIp, DestinationPort, Protocol

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