どうしてもAzure Monitorだけでプロセス監視をしたい
はじめに
Azure VM のプロセス監視といえば、
- VM Insights
- Change Tracking
あたりが真っ先に思い浮かびます。
ただ、要件定義の段階で
- 「そこまでいらない」
- 「コストが合わない」
- 「別の監視ツールがある」
といった理由で採用されないことも多いですよね。
とはいえ現場では、
- オンプレ時代にやっていたので引き続きやりたい
- サードパーティ製の監視ツールは使いたくない
- できるだけ Azure 標準機能だけで済ませたい
という 「どうしてもプロセス監視したい」 状況に直面することがあります。
この記事では、
Azure Monitor + DCR + KQL を使って
「特定のプロセスが動いているか」を割り切って監視する方法 を紹介します。
⚠️ 完全なプロセス監視ではありません
あくまで「最低限・割り切り型」のやり方です。
この記事でできること / できないこと
できること
- 特定プロセスの起動有無の確認
- プロセス数の増減監視
- Azure Monitor アラートによる検知
できないこと
- コマンドラインや引数などの詳細なプロセス情報取得
- リアルタイム監視
- Zabbix 等の専用監視ツールの完全代替
作成するリソース
- データ収集ルール(DCR)
- KQL クエリ
- Azure Monitor アラート
Azure サブスクリプション、リソースグループ、
Azure VM(Windows Server)、Log Analytics Workspace が
すでに作成済みであることを前提とします。
データ収集ルール(DCR)の設定
プロセス情報を収集する
DCR を作成し、VM からプロセス情報を
Log Analytics に送信する設定を行います。
DCR の設定画面から、
- [収集と配信]
- [データソースの追加]
を選択し、パフォーマンスカウンターを追加します。
デフォルトで用意されているカウンターには
個別プロセスを直接指定できるものがないため、
自前で定義する必要があります。
今回は例として、
メモ帳(notepad.exe)だけを収集対象にします。
\Process(notepad.exe)\ID Process (60秒)
すべてのプロセスを正規表現で取ることも可能ですが、
データ量が増えるため今回は避けています。
パフォーマンスカウンターの指定方法については
以下の記事がとても参考になります。
注意点
後続の KQL で使うため、
- プロセスデータ
-
サーバーが起動していれば必ず記録されるデータ
(CPU 使用率やメモリ使用率など)
の両方を収集するようにしてください。
また、[リソース]で対象 VM を指定することも忘れずに。
Azure Monitor Agent(AMA)が入っていない場合、
初回の DCR 関連付け時に自動でインストールされます。
データが見え始めるまで 10 分ほどかかる点に注意してください。
KQL クエリの作成
ここからが本題です。
まずは、
単純にプロセス情報を取得するクエリ を書いてみます。
Perf
| where ObjectName == "Process"
| where InstanceName == "notepad.exe"
| where Computer == "#VM名"
このクエリで、
対象 VM 上の notepad プロセスの ID 情報 が取得できます。
DCR で収集間隔を 60 秒にしているため、
- プロセスが起動している
→ 60 秒ごとにデータが入る - 起動していない
→ データが入らない
という挙動になります。
つまり、
レコード数 = プロセス数 として扱えます。
Azure Monitor の null 問題
ここで 1 つ問題があります。
Azure Monitor のアラートでは、
- プロセスが 0 の場合
→ 0 ではなくnull扱い
になってしまい、
「プロセスが落ちた」ことを検知できません。
そこで、
- サーバーが起動していれば必ず入るデータ(メモリ使用率)
- プロセスデータ
を LEFT OUTER JOIN し、
- サーバーは生きている
- でもプロセスデータがない
場合は
「プロセス数 = 0」 とみなすようにします。
実際の KQL
// ==============================
// VM全体のメモリ使用率を取得
// ==============================
let MemoryUsage = Perf
| where ObjectName == "Memory"
| where CounterName == "% Committed Bytes In Use"
| where Computer == "#VM名"
| summarize
AvgMemoryUsage = avg(todouble(CounterValue))
by Computer, bin(TimeGenerated, 1m);
// ==============================
// notepad.exe のプロセス数を取得
// ==============================
let ProcessData = Perf
| where ObjectName == "Process"
| where InstanceName == "notepad.exe"
| where Computer == "#VM名"
| summarize
notepad_ProcessCount = count()
by Computer, bin(TimeGenerated, 1m);
// ==============================
// メモリ使用率を基準に結合
// ==============================
MemoryUsage
| join kind=leftouter ProcessData on Computer, TimeGenerated
| extend
notepad_ProcessCount = coalesce(notepad_ProcessCount, 0)
| project
Computer,
TimeGenerated,
AvgMemoryUsage,
notepad_ProcessCount
これで、
サーバー稼働中、かつプロセス停止中
という状態を
プロセス数 = 0 として扱えるようになります。
Azure Monitor アラートの設定
ログベースのアラートで、
- メジャー:
notepad_ProcessCount - 条件:
< 1
と設定すれば、
プロセス停止時にアラートを飛ばせます。
まとめ
この方法は、
- Azure Monitor だけで完結させたい
- コストを増やしたくない
- とにかく「動いているか」だけ知りたい
といったケース向けの 割り切りプロセス監視 です。
クエリ前提のため柔軟性は高くなく、
エンタープライズ用途の本格監視には向きません。
それでも、
「どうしても Azure Monitor だけでやりたい」
という場面では、
選択肢の 1 つとして覚えておくと使えるテクニックだと思います。
Discussion