本記事は GitHub Copilot を活用して作成しています。
Azure Monitor の Log Analytics には、データの保存とクエリの方法を制御するための3つのテーブルプランがあります。それぞれのプランには異なる特性があり、用途に応じて使い分けることが重要です。
本記事では、これらのプランの違いを実際に検証し、特に検索クエリのパフォーマンスに焦点を当てて比較します。
テーブルプランとは
Azure Monitor Log Analytics には以下の3つのテーブルプランがあります:
| プラン | 英語名 | 特徴 |
|---|---|---|
| 分析プラン | Analytics Plan | 検索クエリが無料、フル機能のクエリ |
| 基本プラン | Basic Plan | 取り込みコスト削減、単一テーブルのクエリ |
| 補助プラン | Auxiliary Plan | 取り込みコスト大幅削減、単一テーブルのクエリ、検索クエリのパフォーマンスは制限される |
詳細は Azure Monitor ログのデータ プラットフォーム - テーブル プラン を参照してください。
検証の概要
今回の検証では、まったく同じカスタムテキストログを3つのプランのそれぞれで採取し、同一のクエリを実行してパフォーマンスを比較します。
検証環境
architecture-beta
group rg(azure:resource-groups)[Resource Group]
service la(azure:log-analytics-workspaces)[Log Analytics Workspace] in rg
service dcr(azure:data-collection-rules)[Data Collection Rules] in rg
service vm(azure:virtual-machine)[Virtual Machine] in rg
vm:R --> L:dcr
dcr:R --> L:la
- Log Analytics ワークスペース: 1つ
- カスタムテーブル: 3つ(各プラン用)
customtext_analysis_CL(分析プラン)customtext_basic_CL(基本プラン)customtext_auxiliary_CL(補助プラン)
- カスタムテーブル: 3つ(各プラン用)
- データ収集ルール: 1つ
- Windows 仮想マシン: 1台
※記載を省略していますが、Vnet や NSG などのネットワーク関連リソースおよび自動展開で利用するリソースも作成しています。
検証パターン
以下の3つのパターンでクエリパフォーマンスを検証します:
- パターン1: 過去1時間分を検索
- パターン2: RawData の内容を展開
ざっくり手順
- Bicep ファイルの準備
- Bicep デプロイの実行(環境全体の作成)
- パターン1: 検索パフォーマンス検証
- パターン2: RawData の内容を展開
1. Bicep ファイルの準備
検証環境全体を Bicep で作成します。
使用した Bicep ファイルは以下の GitHub リポジトリで公開しています:
https://github.com/NakayamaKento/Azure_Bicep/tree/main/Blog/log_analytics_table_plan
graph TB
subgraph "Azure リソースグループ"
subgraph "ネットワーク"
VNet["Virtual Network<br/>10.0.0.0/16"]
NSG["Network Security Group"]
VNet -->|関連付け| NSG
end
subgraph "コンピュート"
VM["Windows VM<br/>Windows Server 2022<br/>Standard_D4s_v4"]
PIP["Public IP"]
VM -->|関連付け| PIP
VM -->|配置| VNet
end
subgraph "VM 拡張機能"
AMA["Azure Monitor Agent<br/>(Monitoring Agent)"]
CSE["Custom Script Extension"]
VM -->|インストール| AMA
VM -->|インストール| CSE
end
subgraph "スクリプト実行"
CSE -->|ダウンロード & 配置| Scripts["C:\\Scripts\\<br/>- customlog.ps1<br/>- register-imds-startup.ps1"]
Scripts -->|起動時タスク登録| Task["Windows スケジュールタスク<br/>(起動時実行)"]
Task -->|定期実行| LogGen["カスタムログ生成<br/>C:\\Logs\\imds-customtext.log"]
end
subgraph "Log Analytics"
LAW["Log Analytics Workspace"]
Table1["customtext_auxiliary_CL<br/>(Auxiliary Plan)"]
Table2["customtext_basic_CL<br/>(Basic Plan)"]
Table3["customtext_analysis_CL<br/>(Analytics Plan)"]
LAW -->|含む| Table1
LAW -->|含む| Table2
LAW -->|含む| Table3
end
subgraph "データ収集"
DCR["Data Collection Rule"]
AMA -->|データ収集| LogGen
AMA -->|送信| DCR
DCR -->|ルーティング| Table1
DCR -->|ルーティング| Table2
DCR -->|ルーティング| Table3
end
subgraph "デプロイメント自動化"
ManagedID["Managed Identity"]
DeployScript["Deployment Script<br/>(カスタムテーブル作成)"]
RestartScript["Deployment Script<br/>(VM 再起動)"]
SA["Storage Account<br/>(スクリプト用)"]
DeployScript -->|使用| ManagedID
DeployScript -->|REST API 呼び出し| LAW
DeployScript -->|利用| SA
RestartScript -->|VM 再起動| VM
RestartScript -->|利用| SA
RestartScript -->|使用| ManagedID
end
end
GitHub["GitHub Repository<br/>(スクリプト配信)"] -.->|ダウンロード| CSE
classDef network fill:#e1f5ff,stroke:#0078d4,stroke-width:2px
classDef compute fill:#fff4e1,stroke:#ff8c00,stroke-width:2px
classDef monitoring fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
classDef storage fill:#f3e5f5,stroke:#9c27b0,stroke-width:2px
classDef script fill:#fff3e0,stroke:#ff9800,stroke-width:2px
class VNet,NSG,PIP network
class VM,AMA,CSE compute
class LAW,Table1,Table2,Table3,DCR monitoring
class SA,LogGen storage
class ManagedID,DeployScript,RestartScript,Scripts,Task,GitHub script
補足:カスタムテーブル作成用 PowerShell スクリプトの準備
補助プランのテーブルは Azure Portal から作成できず、API を使用する必要があります。
今回はまとめて 3つのプラン(分析、基本、補助)のテーブルをまとめて作成します。
上述のリポジトリでも公開していますが、抜粋して以下に示します。
deploymentScript の実行内容
|
|
現在では Log Analytics ワークスペースに直接データを送信できるため、エンドポイントの作成は不要です。
Azure Monitor のデータ収集エンドポイント - Azure Monitor | Microsoft Learn
2. Bicep デプロイの実行(環境全体の作成)
Bicep ファイルをデプロイして、検証環境全体を作成します。
カスタムログを収集する設定もカスタム スクリプト拡張機能を使って Bicep 内で行っています。
デプロイ後、Azure Portal から作成されたデータ収集ルールを確認できます。
しかし、Azure Portal 上ではデータ収集ルールのすべての設定内容を確認することができません。
JSON 形式であれば設定内容を確認することができます
3. パターン1: 検索パフォーマンス検証
各プランで過去1時間分のデータを取得するクエリを実行し、実行時間を比較します。
クエリ
// 分析プラン
customtext_analysis_CL
| where TimeGenerated > ago(1h)
// 基本プラン
customtext_basic_CL
| where TimeGenerated > ago(1h)
// 補助プラン
customtext_auxiliary_CL
| where TimeGenerated > ago(1h)
結果
| プラン | レコード数 | 実行時間 |
|---|---|---|
| 分析プラン | 58 | 0.453秒 |
| 基本プラン | 58 | 1.090秒 |
| 補助プラン | 58 | 3.617秒 |
考察:
- 分析プランが最も高速で、補助プランは分析プランの約8倍の時間がかかりました
- 基本プランは中間的な性能を示しました
- データ量が少ない場合でも明確な差が見られます
4. パターン2: RawData の内容を展開
RawData を展開するクエリを実行します。
クエリ
// 分析プラン
customtext_analysis_CL
// 先頭4項目
| extend LogDateTime = extract(@"^([^,]+)", 1, RawData),
Sequence = extract(@"^[^,]+,([^,]+)", 1, RawData),
Level = extract(@"^[^,]+,[^,]+,([^,]+)", 1, RawData),
Category = extract(@"^[^,]+,[^,]+,[^,]+,([^,]+)", 1, RawData)
// key=value 部分
| extend vmName = extract(@"vmName=([^;]*)", 1, RawData),
vmSize = extract(@"vmSize=([^;]*)", 1, RawData),
location = extract(@"location=([^;]*)", 1, RawData),
subscriptionId = extract(@"subscriptionId=([^;]*)", 1, RawData),
resourceGroup = extract(@"resourceGroup=([^;]*)", 1, RawData),
privateIps = extract(@"privateIps=([^;]*)", 1, RawData),
publicIps = extract(@"publicIps=([^;]*)", 1, RawData),
scheduledEventsCount = toint(extract(@"scheduledEventsCount=([^;]*)", 1, RawData)),
attestationPresent = tobool(extract(@"attestationPresent=([^;]*)", 1, RawData)),
collectionTs = todatetime(extract(@"collectionTs=([^;]*)", 1, RawData))
// 基本プラン
customtext_basic_CL
// 先頭4項目
| extend LogDateTime = extract(@"^([^,]+)", 1, RawData),
Sequence = extract(@"^[^,]+,([^,]+)", 1, RawData),
Level = extract(@"^[^,]+,[^,]+,([^,]+)", 1, RawData),
Category = extract(@"^[^,]+,[^,]+,[^,]+,([^,]+)", 1, RawData)
// key=value 部分
| extend vmName = extract(@"vmName=([^;]*)", 1, RawData),
vmSize = extract(@"vmSize=([^;]*)", 1, RawData),
location = extract(@"location=([^;]*)", 1, RawData),
subscriptionId = extract(@"subscriptionId=([^;]*)", 1, RawData),
resourceGroup = extract(@"resourceGroup=([^;]*)", 1, RawData),
privateIps = extract(@"privateIps=([^;]*)", 1, RawData),
publicIps = extract(@"publicIps=([^;]*)", 1, RawData),
scheduledEventsCount = toint(extract(@"scheduledEventsCount=([^;]*)", 1, RawData)),
attestationPresent = tobool(extract(@"attestationPresent=([^;]*)", 1, RawData)),
collectionTs = todatetime(extract(@"collectionTs=([^;]*)", 1, RawData))
// 補助プラン
customtext_auxiliary_CL
// 先頭4項目
| extend LogDateTime = extract(@"^([^,]+)", 1, RawData),
Sequence = extract(@"^[^,]+,([^,]+)", 1, RawData),
Level = extract(@"^[^,]+,[^,]+,([^,]+)", 1, RawData),
Category = extract(@"^[^,]+,[^,]+,[^,]+,([^,]+)", 1, RawData)
// key=value 部分
| extend vmName = extract(@"vmName=([^;]*)", 1, RawData),
vmSize = extract(@"vmSize=([^;]*)", 1, RawData),
location = extract(@"location=([^;]*)", 1, RawData),
subscriptionId = extract(@"subscriptionId=([^;]*)", 1, RawData),
resourceGroup = extract(@"resourceGroup=([^;]*)", 1, RawData),
privateIps = extract(@"privateIps=([^;]*)", 1, RawData),
publicIps = extract(@"publicIps=([^;]*)", 1, RawData),
scheduledEventsCount = toint(extract(@"scheduledEventsCount=([^;]*)", 1, RawData)),
attestationPresent = tobool(extract(@"attestationPresent=([^;]*)", 1, RawData)),
collectionTs = todatetime(extract(@"collectionTs=([^;]*)", 1, RawData))
結果
| プラン | レコード数 | 実行時間 |
|---|---|---|
| 分析プラン | 58 | 1.085秒 |
| 基本プラン | 58 | 1.016秒 |
| 補助プラン | 58 | 1.493秒 |
考察:
- パターン1と比較して、そこまで大きな変化は見られません
- 補助プランのパフォーマンスは改善したように見えますが、何度か実行するとムラがあり、パフォーマンスは安定しない印象です
まとめ
Azure Monitor Log Analytics の3つのテーブルプラン(分析、基本、補助)について、実際のカスタムログを使用して検索パフォーマンスを検証しました。
補助プランはクエリが最適化されていない。とドキュメントに記載がありましたが実行した感覚としてはパフォーマンスにムラがありました。
早い時もあれば、遅い時もあるということで確かに最適化はされていなさそうです。