AzureでIISのカスタムフィールド付きW3Cログを取得しLog Analytics Workspaceに格納する

はじめに
こんにちは、yuuchanです。
10月から新しいPJに参画し、Azureを使用するようになりました。
Azureには、これまでのPJで主に使用してきたクラウドサービスであるAWSと似たような要素も多いため、2サービスをうまく関連付けながらキャッチアップを進めています。
さて今回は、VM上で起動しているIISのログを収集する際にカスタムフィールドを含んだW3Cログを収集する方法、および収集したログをLog Analyticsで検索・確認する方法を紹介いたします。
前提
本記事では、
・IISが動いているVM
・ログを格納するLog Analytics Workspace
は作成済みである前提で手順を紹介します。
また本記事では、インターネットからApplication Gatewayを経由してIISへのリクエストを行い動作を確認しています。
Application Gatewayの設定については本記事ではスコープ外といたします。
IISのログ出力設定
まず、IISが動作しているVMにRemote Desktopアプリ等でアクセスし、IISのログ出力設定を行います。
今回、HTTPヘッダの「X-Forwarded-For」の値をログのカスタムフィールドとして追加します。
1. IISマネージャを起動し、「ログ記録」の機能を開きます

2. 「フィールドの選択」を選択し、ログとして取得するフィールドを選択する画面を開きます

3. カスタムフィールドの「フィールドを追加」を選択します

4. 以下のように入力し「OK」を選択します

5. 「適用」を選択し、ログ記録の変更を保存します

6. 最初のメニュー画面(項番1の画面)に戻り、サーバを再起動します

以上でIISのログ出力設定は完了です。
IISでホスティングしているWebサイトなどに通信を行いログファイル(標準ではC:\inetpub\logs\LogFiles\W3SVC1
下にある)を確認すると、以下のように一番右側に「x-forwarded-for」フィールドが追加されたログが記録されていることが分かります。(ログファイルから一部抜粋し、一部IPアドレスを伏せています。)
#Software: Microsoft Internet Information Services 10.0
#Version: 1.0
#Date: 2023-10-25 00:00:09
#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status time-taken x-forwarded-for
2023-10-25 02:46:00 10.7.0.4 GET / - 80 - 10.7.1.5 - - 200 0 0 0 -
2023-10-25 02:46:01 10.7.0.4 GET / - 80 - 10.7.1.7 - - 200 0 0 1 -
2023-10-25 02:46:25 10.7.0.4 GET /favicon.ico - 80 - 10.7.1.7 Mozilla/5.0+(X11;+Linux+x86_64;+rv:73.0)+Gecko/20100101+Firefox/73.0 http://20.78.87.161/ 404 0 2 1 XXX.XXX.XXX.XXX:51438
2023-10-25 02:46:25 10.7.0.4 GET / - 80 - 10.7.1.7 Mozilla/5.0+(X11;+Linux+x86_64;+rv:73.0)+Gecko/20100101+Firefox/73.0 - 200 0 0 1 XXX.XXX.XXX.XXX:51438
2023-10-25 02:46:31 10.7.0.4 GET / - 80 - 10.7.1.7 - - 200 0 0 2 -
2023-10-25 02:46:30 10.7.0.4 GET / - 80 - 10.7.1.5 - - 200 0 0 1 -
以降の手順において、上記ログをJSON形式に変換した上でサンプルファイルとして読み込ませる作業が発生するため、以下のようなJSONファイルを作成しておきます。
[
{
"RawData": "2023-10-25 02:46:00 10.7.0.4 GET / - 80 - 10.7.1.5 - - 200 0 0 0 -"
},
{
"RawData": "2023-10-25 02:46:01 10.7.0.4 GET / - 80 - 10.7.1.7 - - 200 0 0 1 -"
},
{
"RawData": "2023-10-25 02:46:25 10.7.0.4 GET /favicon.ico - 80 - 10.7.1.7 Mozilla/5.0+(X11;+Linux+x86_64;+rv:73.0)+Gecko/20100101+Firefox/73.0 http://20.78.87.161/ 404 0 2 1 XXX.XXX.XXX.XXX:51438"
},
{
"RawData": "2023-10-25 02:46:25 10.7.0.4 GET / - 80 - 10.7.1.7 Mozilla/5.0+(X11;+Linux+x86_64;+rv:73.0)+Gecko/20100101+Firefox/73.0 - 200 0 0 1 XXX.XXX.XXX.XXX:51438"
},
{
"RawData": "2023-10-25 02:46:31 10.7.0.4 GET / - 80 - 10.7.1.7 - - 200 0 0 2 -"
},
{
"RawData": "2023-10-25 02:46:30 10.7.0.4 GET / - 80 - 10.7.1.5 - - 200 0 0 1 -"
}
]
DCEの作成および設定
次に、DCE(Data Collection Endpoint、データ収集エンドポイント)を作成し、作成したDCEにログを収集したいVMを紐つけます。
※DCEについてのより詳細な情報は公式ドキュメントを参照ください。
1. AzureのWebコンソールから「データ収集エンドポイント」のページに移動し、「作成」を選択します
2. 以下例のように必要な項目を入力し、画面下にある「確認と作成」を選択します

3. 検証に成功した旨メッセージが表示されたら、続けて「作成」を選択します
4. 作成したDCEの「リソース」に、ログを収集したいVMを追加します

5. 以下のように、「リソース」にVMが追加されていればDCEの設定は完了です(今回、IISが動作している既存のVMを参照するため名前を伏せております)

カスタムログテーブルおよびDCRの作成
次に、Log Analytics Workspace(以降、LAW)にカスタムログテーブルを作成します。
カスタムフィールドを含まない通常のIISログを収集する場合、W3CIISLogというデフォルトのテーブルにログが格納されますが、今回のようにカスタムフィールドを含むIISログを収集する場合、収集先となるテーブルを作成する必要があります。
また本手順において、合わせてDCR(Data Collection Rule)の作成も行います。
※LAWが未作成の場合は本節の作業を進める前に作成してください。
1. AzureのWebコンソールから「LAW」のページに遷移し、今回ログデータを収集するLAWを選択します
2. 画面左のメニューから「テーブル」を選択します
3. 「作成」->「新しいカスタム ログ (DCR ベース)」を選択します

4. 各項目を以下のように入力し、「新しいデータ収集ルールの作成」を選択します

5. 各項目を以下のように入力し下部にある「完了」を選択します

6. 以下のように全項目が入力されていることを確認し、画面下部の「次へ」を選択します

7. 「IISのログ出力設定」節で作成したJSON形式のログファイルをサンプルデータとしてアップロードします

8. ファイルのアップロードが完了したら、「変換エディター」を選択します

9. 変換エディターに以下のようなKQLを記述後「実行」し、ログが各フィールドに分割されていることを確認したら下部の「適用」を選択します
※予約語である「Date」「Time」はカラム名として使用できないため、代わりに「logDate」「logTime」を使用しています。
source
| extend TimeGenerated = now()
| extend logDate = split(RawData, " ")[0]
| extend logTime = split(RawData, " ")[1]
| extend sIP = split(RawData, " ")[2]
| extend csMethod = split(RawData, " ")[3]
| extend csUriStem = split(RawData, " ")[4]
| extend csUriQuery = split(RawData, " ")[5]
| extend sPort = split(RawData, " ")[6]
| extend csUserName = split(RawData, " ")[7]
| extend cIP = split(RawData, " ")[8]
| extend csUserAgent = split(RawData, " ")[9]
| extend csReferer = split(RawData, " ")[10]
| extend scStatus = split(RawData, " ")[11]
| extend scSubStatus = split(RawData, " ")[12]
| extend scWin32Status = split(RawData, " ")[13]
| extend TimeTaken = split(RawData, " ")[14]
| extend xForwardedFor = split(RawData, " ")[15]

10. 「次へ」を選択します

11. 「作成」を選択します

以上でカスタムログテーブルの作成およびDCRの作成は完了です。
DCRの設定
次に、前節で作成したDCRの設定を行います。
1. AzureのWebコンソールから「Data collection rules」のページに遷移し、前節で作成したDCR(本記事の例では「test-dcr-202311」)を選択します
2. 「データソース」->「追加」を選択します

3. 以下のように各項目を入力し、「次へ:ターゲット」を選択します

補足
ファイルパターン:
IISのログが保存されるWindows上のファイルを入力する
テーブル名:
前節で作成したテーブル名を「_CL」を含めて入力する
Transform:
前節の変換エディターに入力したKQLを入力する
4. ターゲットとして前節でテーブルを作成したLAWを選択し、「データソースの追加」を選択します

ここまでで、DCRへの「データソース」の追加が完了しました。
続いて、「リソース」の追加を行います。
5. 「リソース」->「追加」を選択し、「DCEの作成および設定」節でDCEのリソースに追加したVMと同じVMを追加します


以上でDCRの設定は完了です。
カスタムフィールドを含んだログの表示
ここまでの手順で、カスタムログフィールドを含むIISログを取得しLAWに格納する設定が完了しました。
本節では、収集したログを実際に確認してみます。
1. AzureのWebコンソールから「LAW」のページに遷移し、カスタムログテーブルを作成したLAWを選択します
2. 「ログ」を選択しログ検索用のクエリを入力する画面に遷移します
※「クエリ」という画面が表示された場合は閉じてください

3. 以下のようにクエリを入力し「実行」を選択します

上記クエリを実行すると以下のような結果が得られました。
※IPアドレスを一部マスキングしてあります。

「xForwardedFor」というフィールドに、IISログのカスタムフィールドである「x-forwarded-for」の値が記録されていることが確認できました。
おわりに
いかがでしたでしょうか。
IISの標準ログのみであれば、Log AnalyticsのW3CIISLogテーブルからログを検索・表示することが可能ですが、カスタムフィールドを含む場合はご紹介したような手順で設定が必要になります。
Azureを触り始め約2ヶ月、今後も様々なサービスのキャッチアップを行い、役立つようなトピックを紹介していこうかと思います。