🔨

どうしても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秒)

すべてのプロセスを正規表現で取ることも可能ですが、
データ量が増えるため今回は避けています。

パフォーマンスカウンターの指定方法については
以下の記事がとても参考になります。

https://jpwinsup.github.io/blog/2022/07/15/Performance/SystemResource/PerformanceCounterProcessor/


注意点

後続の 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