Dotazování mapových dat z přehledů virtuálních počítačů

Když povolíte procesy a závislosti, shromažďují se v přehledech virtuálních počítačů data inventáře počítačů a procesů za účelem podpory funkce mapy. Kromě analýzy těchto dat pomocí mapy je možné je dotazovat přímo pomocí Log Analytics. Tento článek popisuje dostupná data a poskytuje ukázkové dotazy.

VM Insights shromažďuje metriky výkonu a připojení, data inventáře počítačů a procesů a informace o stavu a předává je do pracovního prostoru služby Log Analytics ve službě Azure Monitor. Tato data jsou k dispozici pro dotazy ve službě Azure Monitor. Tato data můžete použít ve scénářích, mezi které patří plánování migrace, analýza kapacity, zjišťování a řešení potíží s výkonem na vyžádání.

Důležité

Abyste mohli vytvářet tabulky popisované v tomto článku, musíte mít povolené procesy a závislosti pro přehledy virtuálních počítačů.

Mapování záznamů

Jeden záznam se vygeneruje za hodinu pro každý jedinečný počítač a proces kromě záznamů generovaných při spuštění procesu nebo počítače do přehledů virtuálních počítačů. Pole a hodnoty v tabulce VMComputer se mapuje na pole prostředku počítače v rozhraní API ServiceMap Azure Resource Manageru. Pole a hodnoty v tabulce VMProcess se mapují na pole prostředku procesu v rozhraní API ServiceMap Azure Resource Manageru. Pole _ResourceId odpovídá poli názvu v odpovídajícím zdroji Resource Manageru.

K identifikaci jedinečných procesů a počítačů můžete použít interně generované vlastnosti:

  • Počítač: Pomocí _ResourceId jednoznačně identifikujte počítač v pracovním prostoru služby Log Analytics.
  • Proces: Pomocí _ResourceId můžete jednoznačně identifikovat proces v pracovním prostoru služby Log Analytics.

Vzhledem k tomu, že pro zadaný proces a počítač v zadaném časovém rozsahu může existovat více záznamů, můžou dotazy vrátit více záznamů pro stejný počítač nebo proces. Pokud chcete zahrnout pouze nejnovější záznam, přidejte | summarize arg_max(TimeGenerated, *) by ResourceId ho do dotazu.

Připojení a porty

VMConnection a VMBoundPort poskytují informace o připojeních počítače (příchozí a odchozí) a serverových portech, které jsou na nich otevřené nebo aktivní. Metriky připojení se také zveřejňují prostřednictvím rozhraní API, která poskytují prostředky pro získání konkrétní metriky během časového intervalu. Připojení TCP vyplývající z přijetí na naslouchacím soketu jsou příchozí, zatímco připojení vytvořená připojením k dané IP adrese a portu jsou odchozí. Vlastnost Direction představuje směr připojení, které lze nastavit na hodnotu nebo inbound outbound.

Záznamy v těchto tabulkách se generují z dat hlášených agentem závislostí. Každý záznam představuje pozorování během 1minutového časového intervalu. Vlastnost TimeGenerated označuje začátek časového intervalu. Každý záznam obsahuje informace pro identifikaci příslušné entity, tj. připojení nebo portu a metrik přidružených k dané entitě. V současné době se hlásí pouze síťová aktivita, ke které dochází pomocí protokolu TCP přes protokol IPv4.

Kvůli správě nákladů a složitosti záznamy připojení nepředstavují jednotlivá fyzická síťová připojení. Několik fyzických síťových připojení se seskupí do logického připojení, které se pak projeví v příslušné tabulce. To znamená, že záznamy v VMConnection tabulce představují logické seskupení, nikoli jednotlivá fyzická připojení, která se pozorují. Fyzické síťové připojení sdílející stejnou hodnotu pro následující atributy během daného intervalu jedné minuty se agregují do jednoho logického záznamu v VMConnectionsouboru .

Metriky

VMConnection a VMBoundPort obsahují data metrik s informacemi o objemu odesílaných a přijatých na daném logickém připojení nebo síťovém portu (BytesSent, BytesReceived). Součástí je také doba odezvy, což je doba, po kterou volající čeká na zpracování požadavku přes připojení a odpovídá na ně vzdálený koncový bod (ResponseTimeMax, ResponseTimeMin, ResponseTimeSum). Hlášená doba odezvy je odhad skutečné doby odezvy základního aplikačního protokolu. Počítá se pomocí heuristiky na základě pozorování toku dat mezi zdrojovým a cílovým koncem fyzického síťového připojení. Koncepčně se jedná o rozdíl mezi časem, kdy poslední bajt požadavku opustí odesílatele, a časem, kdy do odpovědi přijde poslední bajt odpovědi. Tato dvě časová razítka slouží k vymezení událostí požadavků a odpovědí u daného fyzického připojení. Rozdíl mezi nimi představuje dobu odezvy jednoho požadavku.

Tento algoritmus je aproximace, která může fungovat s různou mírou úspěchu v závislosti na skutečném aplikačním protokolu používaném pro dané síťové připojení. Aktuální přístup například funguje dobře pro protokoly založené na žádostech, jako jsou HTTP(S), ale nefunguje s jednosměrnými protokoly nebo protokoly založenými na frontě zpráv.

Mezi důležité body, které je potřeba vzít v úvahu, patří:

  1. Pokud proces přijímá připojení na stejné IP adrese, ale přes více síťových rozhraní, je hlášen samostatný záznam pro každé rozhraní.
  2. Záznamy s IP adresou se zástupným znakem neobsahují žádnou aktivitu. Jsou zahrnuté tak, aby představovaly skutečnost, že port na počítači je otevřený pro příchozí provoz.
  3. Kvůli omezení podrobností a objemu dat se záznamy s IP adresou se zástupnými znamény vynechávají, pokud existuje odpovídající záznam (pro stejný proces, port a protokol) s konkrétní IP adresou. Pokud se vynechá záznam IP se zástupnými znamény, vlastnost záznamu s konkrétní IP adresou je nastavená tak, IsWildcardBind aby True indikovala, že port je vystavený přes každé rozhraní počítače pro generování sestav.
  4. Porty vázané pouze na konkrétní rozhraní jsou nastaveny IsWildcardBind na False.

Pojmenování a klasifikace

Pro usnadnění práce je IP adresa vzdáleného konce připojení součástí RemoteIp vlastnosti. U příchozích připojení RemoteIp je stejná jako SourceIpu odchozích připojení, zatímco u odchozích připojení je to stejné jako DestinationIp. Vlastnost RemoteDnsCanonicalNames představuje kanonické názvy DNS hlášené počítačem pro RemoteIp. Vlastnost RemoteDnsQuestions představuje otázky DNS hlášené počítačem pro RemoteIp. Vlastnost RemoveClassification je vyhrazena pro budoucí použití.

Škodlivá IP adresa

Každá RemoteIp vlastnost v VMConnection tabulce se kontroluje proti sadě IP adres se známou škodlivou aktivitou. Pokud se identifikuje RemoteIp jako škodlivý, naplní se následující vlastnosti. Pokud se IP adresa nepovažuje za škodlivou, jsou vlastnosti prázdné.

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

Ukázkové mapové dotazy

Výpis všech známých počítačů

VMComputer | summarize arg_max(TimeGenerated, *) by _ResourceId

Kdy se virtuální počítač naposledy restartoval

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

Souhrn virtuálních počítačů Azure podle image, umístění a skladové položky

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

Výpis kapacity fyzické paměti všech spravovaných počítačů

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

Výpis názvu počítače, DNS, IP adresy a operačního systému

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

Vyhledání všech procesů pomocí jazyka SQL na příkazovém řádku

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

Vyhledání počítače (nejnovějšího záznamu) podle názvu prostředku

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

Vyhledání počítače (nejnovějšího záznamu) podle IP adresy

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

Výpis všech známých procesů na zadaném počítači

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

Výpis všech počítačů se systémem SQL Server

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

Výpis všech jedinečných verzí produktů curl v datovém centru

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

Odesílané bajty a přijaté trendy

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

Které virtuální počítače Azure přenášejí nejvíce bajtů

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

Propojení trendů stavu

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 selhání připojení

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

Vázané porty

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

Počet otevřených portů napříč počítači

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

Určení skóre procesů v pracovním prostoru podle počtu otevřených portů

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

Agregační chování pro každý port

Tento dotaz se pak dá použít k určení skóre portů podle aktivity, například portů s většinou příchozích a odchozích přenosů nebo portů s většinou připojení.

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

Shrnutí odchozích připojení ze skupiny počítačů

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

Další kroky