Abfragen von Zuordnungsdaten aus VM Insights

Wenn Sie Prozesse und Abhängigkeiten aktivieren, werden Computer- und Prozessinventardaten gesammelt, um das Zuordnungsfeature zu unterstützen. Zusätzlich zur Analyse dieser Daten mit der Zuordnung können Sie sie direkt mit Log Analytics abfragen. In diesem Artikel werden die verfügbaren Daten beschrieben und Beispielabfragen bereitgestellt.

VM Insights erfasst Leistungs- und Verbindungsmetriken, Inventurdaten von Computern und Prozessen sowie Informationen zum Integritätsstatus und leitet diese an den Log Analytics-Arbeitsbereich in Azure Monitor weiter. Diese Daten stehen in Azure Monitor für Abfragen zur Verfügung. Diese Daten können in verschiedenen Szenarios von Nutzen sein, z.B. bei der Migrationsplanung, Kapazitätsanalyse, Ermittlung und Ad-hoc-Behebung von Leistungsproblemen.

Wichtig

Prozesse und Abhängigkeiten für VM-Einblicke müssen für die in diesem Artikel erläuterten Tabellen, die erstellt werden sollen, aktiviert sein.

Datensätze zuordnen

Zusätzlich zu den Datensätzen, die beim Starten eines Prozesses oder Computers oder beim Hinzufügen eines Prozesses oder Computers zu VM Insights generiert werden, wird pro Stunde ein Datensatz für jeden eindeutigen Computer und Prozess generiert. Die Felder und Werte in der Tabelle VMComputer sind Feldern der Computerressource in der ServiceMap-Azure Resource Manager-API zugeordnet. Die Felder und Werte in der Tabelle VMProcess sind Feldern der Prozessressource in der ServiceMap-Azure Resource Manager-API zugeordnet. Das Feld _ResourceId entspricht dem Namensfeld in der entsprechenden Resource Manager-Ressource.

Es gibt intern generierte Eigenschaften, mit denen Sie eindeutige Prozessen und Computer identifizieren können:

  • Computer: Verwenden Sie _ResourceId zur eindeutigen Identifizierung eines Computers in einem Log Analytics-Arbeitsbereich.
  • Prozess: Verwenden Sie ResourceId zur eindeutigen Identifizierung eines Prozesses in einem Log Analytics-Arbeitsbereich.

Da für einen angegebenen Prozess und Computer in einem angegebenen Zeitraum möglicherweise mehrere Datensätze vorhanden sind, können Abfragen mehrere Datensätze für denselben Computer oder Prozess zurückgeben. Wenn nur der aktuelle Datensatz zurückgegeben werden soll, fügen Sie der Abfrage | summarize arg_max(TimeGenerated, *) by ResourceId hinzu.

Verbindungen und Ports

VMConnection und VMBoundPort enthalten Informationen zu den Verbindungen eines Computers (eingehend und ausgehend) und den Serverports, die geöffnet bzw. aktiv sind. Verbindungsmetriken werden ebenfalls über APIs zur Verfügung gestellt, die die Möglichkeit zum Abrufen einer bestimmten Metrik während eines Zeitfensters bereitstellen. TCP-Verbindungen, die durch Akzeptieren auf einem lauschenden Socket hergestellt werden, sind eingehend, während Verbindungen, die durch Herstellen einer Verbindung mit einer bestimmten IP-Adresse und einem Port hergestellt werden, ausgehend sind. Die Eigenschaft Direction stellt die Richtung einer Verbindung dar und kann auf inbound oder outbound festgelegt werden.

Die in diesen Tabellen dargestellten Daten wurden aus Daten generiert, die vom Dependency-Agent gemeldet wurden. Jeder Datensatz stellt eine Beobachtung über einen Zeitintervall von einer Minute dar. Die Eigenschaft TimeGenerated gibt den Anfang des Zeitintervalls an. Jeder Datensatz enthält Informationen zum Identifizieren der jeweiligen Entität (d. h. Verbindung oder Port) sowie der dieser Entität zugeordneten Metriken. Derzeit werden nur Netzwerkaktivitäten gemeldet, die über TCP-over-IPv4 anfallen.

Um Kosten und Komplexität im Zaum zu halten, stellen die Verbindungsdatensätze keine einzelnen physischen Netzwerkverbindungen dar. Mehrere physische Netzwerkverbindungen werden in einer logischen Verbindung gruppiert, die dann in der entsprechenden Tabelle wiedergegeben wird. Das heißt, dass die Datensätze in der Tabelle VMConnection eine logische Gruppierung anstelle der beobachteten einzelnen physischen Verbindungen darstellen. Physische Netzwerkverbindungen, die während eines bestimmten einminütigen Intervalls den gleichen Wert für die folgenden Attribute aufweisen, werden in VMConnection zu einem einzelnen logischen Datensatz zusammengefasst.

Metriken

VMConnection und VMBoundPort beinhalten Metrikdaten mit Informationen über das Datenvolumen, das an bestimmte logische Verbindungen oder bestimmte Netzwerkports gesendet und von ihnen empfangen wurde (BytesSent, BytesReceived). Außerdem ist die Antwortzeit enthalten, die angibt, wie lange der Anrufer auf eine Anforderung wartet, die über eine Verbindung gesendet wird, die vom Remoteendpunkt verarbeitet und beantwortet wird (ResponseTimeMax, ResponseTimeMin, ResponseTimeSum). Die gemeldete Antwortzeit ist eine Schätzung der tatsächlichen Antwortzeit des zugrundeliegenden Anwendungsprotokolls. Sie wird mit heuristischen Verfahren auf der Grundlage der Beobachtung des Datenflusses zwischen dem Quell- und dem Zielende einer physischen Netzwerkverbindung berechnet. Konzeptionell handelt es sich um die Differenz zwischen dem Zeitpunkt, zu dem das letzte Byte einer Anforderung den Sender verlässt, und dem Zeitpunkt, zu dem das letzte Byte der Antwort wieder bei ihm eintrifft. Diese beiden Zeitstempel werden verwendet, um Anforderungs- und Antwortereignisse für eine bestehende physische Verbindung darzustellen. Die Differenz zwischen ihnen stellt die Antwortzeit für eine einzelne Anforderung dar.

Diese Algorithmen stellen eine Annäherung dar, die abhängig von dem für eine bestimmte Netzwerkverbindung tatsächlich verwendeten Anwendungsprotokoll mehr oder weniger erfolgreich funktionieren kann. Beispielsweise funktioniert der aktuelle Ansatz gut bei Anforderungs-/Antwort-basierten Protokollen wie HTTP(S), er funktioniert aber nicht bei unidirektionalen oder auf Nachrichtenwarteschlangen basierenden Protokollen.

Einige wichtige Punkte sind zu beachten, unter anderem:

  1. Wenn ein Prozess Verbindungen an der gleichen IP-Adresse, aber über mehrere Netzwerkschnittstellen annimmt, wird für jede Schnittstelle ein separater Datensatz gemeldet.
  2. Datensätze mit Platzhalter-IP-Adresse enthalten keine Aktivitäten. Sie werden aufgenommen, um die Tatsache darzustellen, dass ein Port auf dem Computer für eingehenden Datenverkehr offen ist.
  3. Um Ausführlichkeit und Datenvolumen zu verringern, werden Datensätze mit Platzhalter-IP-Adressen weggelassen, wenn es einen übereinstimmenden Datensatz (für den gleichen Prozess, Port und das gleiche Protokoll) mit einer bestimmten IP-Adresse gibt. Wenn ein Datensatz mit Platzhalter-IP-Adresse weggelassen wird, wird die Datensatzeigenschaft IsWildcardBind mit der bestimmten IP-Adresse auf True festgelegt, um anzuzeigen, dass der Port über jede Schnittstelle des berichtenden Computers offengelegt wird.
  4. Für Ports, die nur an eine bestimmte Schnittstelle gebunden sind, ist IsWildcardBind auf False festgelegt.

Benennung und Klassifizierung

Der Einfachheit halber ist die IP-Adresse des Remoteendpunkts einer Verbindung in der Eigenschaft RemoteIp enthalten. Für eingehende Verbindungen ist RemoteIp identisch mit SourceIp, während das Element für ausgehende Verbindungen mit DestinationIp übereinstimmt. Die Eigenschaft RemoteDnsCanonicalNames stellt die kanonischen DNS-Namen dar, die vom Computer für RemoteIp gemeldet werden. Die Eigenschaft RemoteDnsQuestions stellt die DNS-Fragen dar, die vom Computer für RemoteIp gemeldet werden. Die RemoveClassification-Eigenschaft ist für die zukünftige Verwendung reserviert.

Schädliche IP-Adressen

Jede Eigenschaft RemoteIp in der Tabelle VMConnection wird anhand einer Sammlung von IPs überprüft, die für schädliche Aktivitäten bekannt sind. Wenn die RemoteIp als böswillig identifiziert wird, werden die folgenden Eigenschaften aufgefüllt. Wenn die IP nicht als bösartig eingestuft wird, bleiben die Eigenschaften leer.

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

Beispielzuordnungsabfragen

Auflisten aller bekannten Computer

VMComputer | summarize arg_max(TimeGenerated, *) by _ResourceId

Letzter Neustart des virtuellen Computers

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

Zusammenfassung von virtuellen Azure-Computern nach Image, Speicherort und SKU

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

Auflisten der physischen Arbeitsspeicherkapazität aller verwalteten Computer

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

Auflisten von Computernamen, DNS, IP und Betriebssystem

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

Suchen nach allen Prozesse mit "sql" in der Befehlszeile

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

Suchen eines Computers (aktuellster Datensatz) anhand des Ressourcennamens

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

Suchen eines Computers (aktuellster Datensatz) anhand der IP-Adresse

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

Auflisten aller bekannten Prozesse auf einem angegebenen Computer auf

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

Auflisten aller Computer, auf denen SQL Server ausgeführt wird

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

Auflisten aller eindeutigen Produktversionen von „curl“ im eigenen Rechenzentrum

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

Gesendete Bytes und empfangene Trends

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

Virtuelle Azure-Computer, die die meisten Bytes übertragen

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

Trends zum Linkstatus

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

Trend zu Verbindungsfehlern

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

Gebundene Ports

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

Anzahl der offenen Ports auf Computern

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

Bewerten der Prozesse im Arbeitsbereich anhand ihrer offenen Ports

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

Aggregieren des Verhaltens für jeden Port

Anschließend kann diese Abfrage verwendet werden, um Ports anhand der Aktivität zu bewerten, z. B. Ports mit dem meisten eingehenden/ausgehenden Datenverkehr oder Ports mit den meisten Verbindungen.

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

Zusammenfassen der ausgehenden Verbindungen für eine Gruppe von Computern

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

Nächste Schritte