VM Insights からのマップ データのクエリ
VM insights でプロセスと依存関係を有効にすると、マップ機能をサポートするために、コンピューターとプロセスのインベントリ データが収集されます。 このデータについては、マップを使用して分析できるだけでなく、Log Analytics を使用して直接クエリを実行することもできます。 この記事では、使用可能なデータについて説明し、クエリの例を示します。
VM Insights では、パフォーマンスと接続のメトリック、コンピューターとプロセスのインベントリ データ、および正常性状態の情報の収集と、Azure Monitor 内の Log Analytics ワークスペースへの転送が行われます。 このデータは、Azure Monitor でクエリ用に使用できます。 このデータは、移行計画、容量の分析、探索、必要に応じたパフォーマンスのトラブルシューティングといったシナリオに適用できます。
重要
この記事で説明するテーブルを作成するには、それらのテーブルについて VM insights のプロセスと依存関係を有効にしておく必要があります。
Map レコード
レコードは、個々のプロセスまたはコンピューターが起動または VM Insights に追加されたときに生成されるほか、個々の一意なコンピューターとプロセスについて 1 時間ごとに 1 件ずつ生成されます。 VMComputer テーブルのフィールドと値は、ServiceMap Azure Resource Manager API のマシン リソースのフィールドにマップされます。 VMProcess テーブルのフィールドと値は、ServiceMap Azure Resource Manager API のプロセス リソースのフィールドにマップされます。 _ResourceId
フィールドは、対応する Resource Manager リソースの名前フィールドと一致します。
個々のプロセスとコンピューターの識別に使用できる、内部生成されたプロパティがあります。
- コンピューター: Log Analytics ワークスペース内のコンピューターは _ResourceId を使用して一意に識別されます。
- プロセス: Log Analytics ワークスペース内のプロセスは _ResourceId を使用して一意に識別されます。
指定の時間範囲にある指定のプロセスとコンピューターについては、複数のレコードが存在できるため、クエリは、同じコンピューターまたはプロセスに対して複数のレコードを返すことがあります。 最新のレコードのみが返されるようにするには、| summarize arg_max(TimeGenerated, *) by ResourceId
をクエリに追加します。
接続とポート
VMConnection と VMBoundPort では、マシンの接続 (受信および送信) と、それらのマシンで開かれている/アクティブであるサーバー ポートの情報が得られます。 接続メトリックは、時間枠の間に特定のメトリックを取得する手段を提供する API を介して公開されています。 リスニング ソケットで "受諾する" ことで得られる TCP 接続は受信ですが、所定の IP とポートに "接続する" ことで作成される接続は送信です。 Direction
プロパティは接続の方向を表します。これは inbound
または outbound
に設定できます。
これらのテーブル内のレコードは、Dependency Agent によって報告されるデータから生成されます。 いずれの記録も、1 分の時間間隔での観測を表します。 TimeGenerated
プロパティは、時間間隔の開始を示します。 各レコードには、それぞれのエンティティを特定する情報、つまり接続またはポートと、そのエンティティに関連付けられたメトリックが含まれています。 現在のところ、TCP over IPv4 を使用することで発生するネットワーク アクティビティのみが報告されます。
コストと複雑さを管理するため、接続レコードは個々の物理ネットワーク接続を表すものではありません。 複数の物理ネットワーク接続は、論理接続にグループ化され、その後それぞれのテーブルに反映されます。 つまり、VMConnection
テーブル内のレコードは論理的なグループに対応しており、観察対象である個々の物理接続に対応するものではありません。 1 分単位で区切られた 1 つの期間内において、以下の属性値が共通である物理ネットワーク接続は、VMConnection
内では 1 つの論理レコードにまとめて扱われます。
メトリック
VMConnection と VMBoundPort では、当該の論理接続またはネットワーク ポート (BytesSent
、BytesReceived
) で送受信されたデータの量に関する情報を反映したメトリック データを取得できます。 また、応答時間 (ResponseTimeMax
、ResponseTimeMin
、ResponseTimeSum
) も知ることができます。これは、個々の接続を介して送信された要求がリモート エンドポイントによって処理され、応答が返されるまでの、呼び出し元に発生した待ち時間です。 報告される応答時間は、内在するアプリケーション プロトコルの実際の応答時間の推定値です。 これは、物理ネットワーク接続の送信元と送信先の間のデータ フローの観察に基づき、経験則を使用して計算されます。 これは、概念上、要求の最後のバイトが送信者を離れる時間と、応答の最後のバイトが送信者に返される時間の差です。 これらの 2 つのタイムスタンプは、所定の物理接続で要求イベントと応答イベントを明確化するために使用されます。 これらの差は、1 つの要求の応答時間を表します。
このアルゴリズムは近似値を求めるものであり、正確さの度合いは、当該ネットワーク接続で実際にどのようなアプリケーション プロトコルが使用されるかによって異なります。 たとえば、現在のアプローチは、HTTP(S) のような要求 - 応答ベースのプロトコルでは正しく動作しますが、一方向またはメッセージ キュー ベースのプロトコルでは動作しません。
たとえば、以下のような事項を考慮する必要があります。
- プロセスが同じ IP アドレスでも複数のネットワーク インターフェイスで接続を受け入れる場合、インターフェイスごとに別のレコードが報告されます。
- ワイルドカード IP 付きレコードにはアクティビティはありません。 これらは、マシン上のポートが受信トラフィックにオープンであるという事実を表すために加えられています。
- 冗長性とデータ量を減らすために、ワイルドカード IP 付きレコードは、特定の IP アドレスと一致するレコード (同じプロセス、ポート、プロトコル) がある場合は省略されます。 ワイルドカード IP レコードが省略された場合、特定の IP アドレスが指定された
IsWildcardBind
レコード プロパティは、ポートが報告マシンのあらゆるインターフェイスで公開されることを示すTrue
に設定されます。 - 特定のインターフェイスにのみバインドされているポートでは、
IsWildcardBind
はFalse
に設定されます。
命名と分類
便宜上、接続のリモート側の IP アドレスは RemoteIp
プロパティに加えられています。 受信接続の場合、RemoteIp
は SourceIp
と同じですが、送信接続の場合は DestinationIp
と同じです。 RemoteDnsCanonicalNames
プロパティは、RemoteIp
向けにマシンにより報告される DNS 正規名を表します。 RemoteDnsQuestions
プロパティは、RemoteIp
についてマシンから報告された DNS の質問を表します。 RemoveClassification
プロパティは、将来使用するために予約されています。
悪意のある IP
VMConnection
テーブルに含まれる個々の RemoteIp
プロパティは、悪意ある既知のアクティビティに関連した一連の IP と照合されます。 悪意あるものとして識別された RemoteIp
については、以下のプロパティが設定されます。 悪意あるものと見なされない IP については、これらのプロパティは空です。
MaliciousIp
IndicatorThreadType
Description
TLPLevel
Confidence
Severity
FirstReportedDateTime
LastReportedDateTime
IsActive
ReportReferenceLink
AdditionalInformation
サンプルのマップのクエリ
既知のすべてのマシンを一覧表示する
VMComputer | summarize arg_max(TimeGenerated, *) by _ResourceId
VM が最後に再起動された時期を調べる
let Today = now(); VMComputer | extend DaysSinceBoot = Today - BootTime | summarize by Computer, DaysSinceBoot, BootTime | sort by BootTime asc
Azure VM の概要をイメージ、場所、SKU 別に表示する
VMComputer | where AzureLocation != "" | summarize by Computer, AzureImageOffering, AzureLocation, AzureImageSku
すべての管理対象コンピューターの物理メモリ容量を一覧表示する
VMComputer | summarize arg_max(TimeGenerated, *) by _ResourceId | project PhysicalMemoryMB, Computer
コンピューター名、DNS、IP、OS を一覧表示する
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 VM を調べる
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
次のステップ
- Azure Monitor でログ クエリの作成を始めるには、Log Analytics の使用方法に関する記事を参照してください。
- 詳細については、検索クエリの記述に関する記事を参照してください。