🥯

Azure Monitor で プロセス監視(Azure Monior Agent)

2024/03/07に公開

はじめに

本記事では Azure Monitor Agent を利用して Windows / Linux 仮想マシンのプロセス監視を試してみます。
なお、他にどういう方法があるかは以下の記事を参照ください。
https://zenn.dev/microsoft/articles/azuremonitor-processes

Azure Monitor Agent は、Log Analytics Agent の後継となる新しいエージェントです。
Azure Monitor Agent を利用して 各種メトリック を取得することができ、Azure Log Analytics (Perf テーブル) に保存することもできます。
プロセス関連のメトリック(例えば プロセス毎の CPU 使用率)を取得してログ保存するように Data Collection Rules (DCR) を構成しておき、監視対象プロセスの状況を調べる Kusto クエリ を実行することもできます。

取得したメトリックをそのままアラートルールとして採用することは難しいと考えたため、今回は一度ログとして保存し、そのログを利用してアラートルールを設定する方法を試しています。

仕組み

Azure Monitor Agent は、Log Analytics Agent の後継となる新しいエージェントです。
エージェントが収集する項目は、Data Collection Rules (DCR) で定義することができます。
DCR を作成する際、"基本" タブから良く使われるCPU使用率など選択することもできますが、"カスタム" タブで \Process(プロセス名)\Thread Count のような 任意のメトリック を指定することもできます。これにより、Windows の場合にはパフォーマンスモニターとして指定できる値、Linux の場合には、/proc 以下の情報を取得することができます。
収集した結果は、 Log Analytics に格納することができ、 Perf テーブルに格納されます。

今回、 Windows で取得する候補は以下あたりで、任意のプロセス名を指定するか、全プロセスを * で指定するか、使い分ける感じでしょうか。

  • \Process(プロセス名)\Thread Count
  • \Process(プロセス名)\% Processor Time
  • \Process(*)\Thread Count
  • \Process(*)\% Processor Time

なお、パフォーマンスカウンター自体については、以下記事が参照になります。
https://jpwinsup.github.io/blog/2022/07/15/Performance/SystemResource/PerformanceCounterProcessor/

さて、収集した \Process(プロセス名)\Thread Count ですが、プロセスのスレッド数を取得できるのであれば、プロセスが停止した場合にはこの値が 0 となってアラートを出せるのでしょうか?
実は、プロセスが停止した場合には、収集対象自体が存在しなくなるため、\Process(プロセス名)\Thread Count は、値自体が記録されません。
そのため、例えば \Process(プロセス名)\Thread Count の値が 0 (スレッド数 が 0 の場合) に等しい場合といった条件で アラートルール を作成したとしても、上手く動作しません。

プロセスの停止を検知するためには一工夫が必要となり、例えば、ログが記録されなくなったらアラートを出す、といった方法を取ることになります。
近い考え方としては Hertbeat を用いた死活監視のようなものでしょうか。

https://jpazmon-integ.github.io/blog/LogAnalytics/MonitorVM/

やってみる、 Windows の場合

DCR の設定

まずは DCR の設定を行います。
今回は分かりやすいように、監視対象プロセスを msedge(Edgeブラウザ のプロセス、簡単に起動/停止の動確ができるので) としてみましょう。

Azure Portal から Azure Monitor に移動し、データ収集ルール を選んで DCR の作成を開始します。
基本タブでは、ルール名や、DCRを保存するリソースグループ、 Region、プラットフォームの種類 Windows を選択します。
続くリソースタブでは、ログ収集の対象となる VM を選択します。
そののち、収集と配信のタブで、収集するログの種類を選択します。
[+データソースの追加] を選択し、[パフォーマンスカウンター] を選択します。


カスタムタブにて、 \process(msedge)\Thread Count を指定しました。


また、ターゲットとして、保存先となる Log Analytics ワークスペースも指定して、DCR の設定は完了です。

ログ取得の確認

さて、収集対象の VM で、Edge ブラウザを起動してしばらく待つと、先ほど DCR で取得するよう指定したメトリックが収集されるはずです。
収集対象 VM のメトリック欄を開き、
 メトリック名前空間 : 仮想マシンのゲスト
 メトリック : \process(msedge)\Thread Count
が選択できるはずですので、これを選択してグラフ表示してみます。


\process(msedge)\Thread Count が取得できていますね!

Log Analytics に格納された Perf テーブルを参照して、クエリでもmsedge の スレッド数を確認してみます。

Kusto Query 例
Perf 
| where ObjectName == "Process"
| where InstanceName == "msedge"
| where CounterName == "Thread Count"


メトリックとしてグラフ表示できた \process(msedge)\Thread Count と同じような値が、ログとして取得できていることがわかります。

アラートの設定

さて、仕組みのところでご紹介した通り、メトリックを利用して 値 = 0 といった条件ではアラートが難しいため、ログ件数を利用したアラートルールを設定してみます。
クエリを以下のよう少し改変し、直近5分間に出力されたログから、「msedge の スレッド数」についてのログの件数をカウントする、ようにしてみました。
正常であれば「msedge の スレッド数」 が毎分報告されるはずですので、1分毎 に 1件 ログが出力されるはずです。

Kusto Query 例
Perf 
| where TimeGenerated > ago(5min)
| where ObjectName == "Process"
| where InstanceName == "msedge"
| where CounterName == "Thread Count"
| summarize count() by Computer, InstanceName, bin(TimeGenerated, 1m)

アラートルールの設定は、上記クエリの結果が 0 件の場合にアラートを出すように設定しておきます。(直近5分間に出力されたログが 0 件の場合にアラートを出す、ということです)

  • 評価の頻度 : 5分 : アラートの検索クエリが実行される間隔。つまり、5 分ごとにクエリを実行します。
  • 集計の粒度 : 5分 : 評価の頻度に基づいて実行されるクエリが、評価を行う際に評価の対象とする期間。
  • しきい値/演算子 : 0 と 等しい : クエリの実行結果が 0 件の場合にアラートを出すように設定しています。

動作確認

さて、アラートルールを設定したら、実際に Edge ブラウザを停止してみましょう。
アラートが出るまではしばらく時間がかかりますが、以下の通りアラートが発生し、アクションとして指定したアラートメールが飛んできました。


やってみる、 Linux の場合

DCR の設定

今度は Linux の場合でも試してみます。
手元にあった Linux マシンとして、 Quaaga を動作させている Linux VM がありましたので、監視対象プロセスは zebra として進めてみます。

Linux の場合には、DCR では、パフォーマンスカウンターの 基本タブ にて Process を取得するように指定ができます。
念のため、Process を取得するようにした状態で、カスタム タブを開いてみると、Process(*)\Pct User Time の指定が入っており、全てのプロセスの CPU 使用率を取得するように設定ができています。

また、ログとして、LogAnalytics ワークスペースへ保存するように、ターゲットを指定をしておきます。

ログ取得の確認

さて、しばらく待つと 収集対象 VM からメトリックが収集されるはずです。
収集対象 VM のメトリック欄を開き、
 メトリック名前空間 : azure.vm.linux.guestmetrics
 メトリック : \procstat/cpu_time_system
を選択します。いったんグラフが表示されますが、つづけて [分割を適用する] を選択して 値 として Process_name を選択します。
すると、プロセス名ごとの CPU 使用率がグラフ表示されます。

[フィルター の追加] を選択すると、任意のプロセス名を指定して、そのプロセスの CPU 使用率を確認することができます。

では、今回も Log Analytics に格納された Perf テーブルを参照して、クエリでも確認してみます。
今回は summarize max(TimeGenerated) を使って、一番最後に出力されたログを取得してみます。

Kusto Query Linux例
Perf 
| where ObjectName == "Process" and CounterName == "Pct User Time"
| where Computer == "quaggavm"
| where InstanceName == "zebra"
| summarize max(TimeGenerated) by Computer,InstanceName

アラートの設定

さて、今度は Windows の場合とは少し違うやり方にしてみます。前述のクエリを、少しだけ変えてみます。
summarize の結果(zebra プロセスの最後のログ) を LastCall として取得し、LastCall が 5分以上前 の場合に、クエリの実行結果が得られるようにしました。

Kusto Query Linux例
Perf 
| where ObjectName == "Process" and CounterName == "Pct User Time"
| where Computer == "quaggavm"
| where InstanceName == "zebra"
| summarize LastCall = max(TimeGenerated) by Computer,InstanceName
| where LastCall < ago(5m)

対象プロセスが正常稼働している場合には、最新のログが 5分以内にあるためクエリの < ago(5m) 条件には引っかかりません。
万が一、対象プロセスが停止すると、それ以上ログが記録されなくなり、最後のログから 5分以上 経過すると、クエリの実行結果が得られる形です。

●正常時は、クエリ結果無し

●異常時は、クエリ結果あり

このクエリ結果を利用して、アラートルールを設定します。

動作確認

それでは、実際に zebra プロセスを停止してみます。

# zebra のプロセスを停止
/etc/init.d/zebra stop

# zebra のプロセスを起動
/etc/init.d/zebra start

アラートが出るまではしばらく時間がかかりますが、以下の通りアラートが発生し、アクションとして指定したアラートメールが飛んできました。

まとめ

  • Windows : DCR でパフォーマンスカウンターを収集。 \Process(プロセス名)\Thread Count のようなカスタムを行う
  • Linux : DCR でパフォーマンスカウンターを収集。procstat/cpu_time_system を分割し、フィルタ= (プロセス名) とすることで、CPU使用率を取得可能
  • どちらも LogAnalytics へ格納することで Perf テーブルを参照して集計することが可能。クエリを作成して、アラートルールを設定することが可能。

参考URL

https://jpazmon-integ.github.io/blog/LogAnalytics/AMALinux_Perf/

https://jpazmon-integ.github.io/blog/LogAnalytics/MonitorVM/

https://zenn.dev/microsoft/articles/azuremonitor-processes

Microsoft (有志)

Discussion