Compartir a través de


Consulta de datos de asignación desde VM Insights

Al habilitar procesos y dependencias, en VM Insights, los datos de inventario de equipos y procesos se recopilan para admitir la característica de asignación. Además de analizar estos datos con el mapa, puede consultarlos directamente con Log Analytics. En este artículo se describen los datos disponibles y se proporcionan consultas de ejemplo.

VM Insights recopila métricas de rendimiento y conexión, datos de inventario de proceso y equipo, e información sobre el estado, y reenvía estos datos al área de trabajo de Log Analytics en Azure Monitor. Estos datos están disponibles para consulta en Azure Monitor. Estos datos se pueden aplicar a escenarios que incluyen la planeación de la migración, el análisis de la capacidad, la detección y la solución de problemas de rendimiento a petición.

Importante

Debe tener los procesos y dependencias habilitados para VM Insights para las tablas que se describen en este artículo que se van a crear.

Registros de asignación

Se genera un registro por hora para cada equipo único y proceso además de los registros que se generan cuando se inicia un proceso o equipo o se agrega a VM Insights. Los campos y valores de la tabla VMComputer se asignan a los campos del recurso Máquina en la API de Azure Resource Manager de ServiceMap. Los campos y valores de la tabla VMProcess se asignan a los campos del recurso de proceso en la API de Azure Resource Manager de ServiceMap. El campo _ResourceId coincide con el campo de nombre en el recurso de Resource Manager correspondiente.

Hay propiedades generadas internamente que puede usar para identificar los equipos y procesos únicos:

  • Equipo: use _ResourceId para identificar de forma única un equipo en un área de trabajo de Log Analytics.
  • Proceso: use _ResourceId para identificar de forma única un proceso en un área de trabajo de Log Analytics.

Puesto que pueden existir varios registros para un proceso y equipo especificados en un intervalo de tiempo concreto, las consultas pueden devolver más de un registro para el mismo proceso o equipo. Para incluir solo el registro más reciente, agregue | summarize arg_max(TimeGenerated, *) by ResourceId a la consulta.

Conexiones y puertos

VMConnection y VMBoundPort proporcionan información acerca de las conexiones de una máquina (entrante y saliente) y los puertos de servidor que están abiertos o activos en ellos. Las métricas de conexión también se exponen a través de API que proporcionan los medios para obtener una métrica específica durante un período de tiempo. Las conexiones TCP resultantes de aceptar en un socket de escucha son de entrada, mientras que las creadas al conectarse a un puerto y una dirección IP determinados son de salida. La propiedad Direction representa la dirección de una conexión, que se puede establecer en inbound o en outbound.

Los registros de estas tablas se generan a partir de los datos que notifica Dependency Agent. Cada registro representa una observación en un intervalo de tiempo de un minuto. La propiedad TimeGenerated indica el inicio del intervalo de tiempo. Cada registro contiene información para identificar la entidad correspondiente; es decir, conexión o puerto, así como las métricas asociadas con esa entidad. Actualmente, solo se notifica la actividad de red que tiene lugar mediante TCP a través de IPv4.

Para administrar el costo y la complejidad, los registros de conexión no representan conexiones de red físicas individuales. Varias conexiones de red físicas se agrupan en una conexión lógica, que, a continuación, se refleja en la tabla correspondiente. Es decir, los registros de VMConnection tabla representan una agrupación lógica y no las conexiones físicas individuales que se observan. La conexión de red física que comparte el mismo valor para los atributos siguientes durante un intervalo de un minuto determinado, se agrega a un único registro lógico en VMConnection.

Métricas

VMConnection y VMBoundPort incluyen datos de métricas con información sobre el volumen de datos enviados y recibidos en una conexión lógica determinada o puerto de red (BytesSent, BytesReceived). También se incluye el tiempo de respuesta, que es cuánto tiempo espera el autor de la llamada a una solicitud enviada a través de una conexión a la que se va a procesar y responder mediante el punto de conexión remoto (ResponseTimeMax, ResponseTimeMin, ResponseTimeSum). El tiempo de respuesta notificado es una estimación del tiempo de respuesta real del protocolo de aplicación subyacente. Se calcula mediante heurística basada en la observación del flujo de datos entre el origen y el destino final de una conexión de red física. Conceptualmente, es la diferencia entre el momento en que el remitente deja el último byte de una solicitud y el momento en que regresa el último byte de la respuesta. Estas dos marcas de tiempo se utilizan para delinear los eventos de solicitud y respuesta de una conexión física concreta. La diferencia entre ellas representa el tiempo de respuesta de una única solicitud.

Este algoritmo es una aproximación que puede funcionar con diferentes grados de éxito en función del protocolo de aplicación real usado para una conexión de red determinada. Por ejemplo, el enfoque actual funciona bien para protocolos basados en solicitudes y respuestas, como HTTP(S), pero no funciona con protocolos unidireccionales ni basados en colas de mensajes.

Algunos puntos importantes que se deben tener en cuenta son:

  1. Si un proceso acepta conexiones en la misma dirección IP, pero a través de varias interfaces de red, se notificará un registro independiente para cada interfaz.
  2. Los registros con IP comodín no contendrán ninguna actividad. Se incluyen para representar el hecho de que un puerto del equipo está abierto al tráfico de entrada.
  3. Para reducir el nivel de detalle y el volumen de datos, los registros con dirección IP de carácter comodín se omitirán cuando haya un registro coincidente (para el mismo proceso, puerto y protocolo) con una dirección IP específica. Cuando un registro de dirección IP comodín se omite, la propiedad del registro IsWildcardBind con la dirección IP específica se definirá como True para indicar que el puerto se expone a través de cada interfaz de la máquina que notifica.
  4. Los puertos que están enlazados solo en una interfaz específica tienen IsWildcardBind definido como False.

Nomenclatura y clasificación

Para mayor comodidad, la dirección IP del extremo remoto de una conexión se incluye en la propiedad RemoteIp. Para las conexiones entrantes, RemoteIp coincide con SourceIp, mientras que, para las conexiones salientes, coincide con DestinationIp. La propiedad RemoteDnsCanonicalNames representa los nombres canónicos DNS que notifica la máquina para RemoteIp. La propiedad RemoteDnsQuestions representa los preguntas de DNS que notifica la máquina para RemoteIp. La propiedad RemoveClassification se reserva para uso futuro.

Direcciones IP malintencionadas

Todas las RemoteIp propiedad de la tabla VMConnection se comprueban con un conjunto de direcciones IP con actividad malintencionada conocida. Si el RemoteIp se identifica como malintencionado, se rellenan las siguientes propiedades. Si la dirección IP no se considera malintencionada, las propiedades están vacías.

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

Consultas de mapa de ejemplo

Enumerar todas las máquinas conocidas

VMComputer | summarize arg_max(TimeGenerated, *) by _ResourceId

¿Cuándo se ha reiniciado la máquina virtual por última vez

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

Resumen de máquinas virtuales de Azure por imagen, ubicación y de SKU

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

Enumerar la capacidad de memoria física de todos los equipos administrados

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

Enumeración del nombre del equipo, DNS, IP y del sistema operativo

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

Buscar todos los procesos con "sql" en la línea de comandos

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

Buscar una máquina (registro más reciente) por nombre de recurso

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

Buscar una máquina (registro más reciente) por dirección IP

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

Enumerar todos los procesos conocidos en una máquina especificada

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

Enumerar todos los equipos que ejecutan SQL Server

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

Enumerar todas las versiones de producto únicas de curl en mi centro de datos

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

Bytes enviados y recibidos tendencias

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

Qué máquinas virtuales de Azure transmiten la mayoría de los bytes

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

Tendencias de estado de vínculo

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

Tendencia de errores de conexión

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

Puertos enlazados

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

Número de puertos abiertos entre máquinas

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

Puntuación procesos en el área de trabajo por el número de puertos que tienen abiertos

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

Comportamiento agregado para cada puerto

A continuación, esta consulta se puede usar para puntuar los puertos por actividad (por ejemplo, puertos con más tráfico entrante y saliente o puertos con más conexiones).

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

Resumir las conexiones salientes de un grupo de máquinas

// 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

Pasos siguientes