# ログトレース

EMQX 5.0では、特定のクライアントID、トピック、IPアドレス、またはルールIDに対してリアルタイムのデバッグレベルログ出力を可能にするログトレース機能を導入しました。これにより、過剰なログによるシステムパフォーマンスへの影響を抑えつつ、本番環境での詳細なデバッグが可能となり、EMQXの問題診断と解決の効率が向上します。

## ログトレースの仕組み

ログトレース機能は、Erlangの組み込みLogger Filter関数を利用して実装されており、全体のメッセージスループットへの影響はほとんどありません。EMQXは独立したファイルハンドラーを用いてトレースログを永続化し、クライアント接続ごとに独立したプロセスを作成してメッセージを処理します。

クライアントがメッセージを送信すると、その接続を担当するプロセスはメッセージがトレースフィルターで設定されたルールに合致するかをチェックします。例えば、指定されたクライアントIDからのメッセージかどうかを判定します。

- メッセージがフィルター条件に合致する場合、プロセスはそれを人間が読みやすいトレースイベントに変換し、非同期で該当するファイルハンドラーに送信します。
- それ以外の場合は、通常通りメッセージを処理します。

ファイルハンドラーはトレースイベントをそれぞれのトレースファイルにディスク上で永続化する役割を担います。

ノードやEMQXクラスター全体が再起動された場合でも、未完了のログトレースは自動的に再開されます。

## ログトレースを使う理由

ログトレース機能は、本番環境でのデバッグや監視において以下の重要な理由から効果的なツールです。

- **安全性**：フィルタリング処理はクライアントごとに独立して行われるため、ファイルハンドラーの過負荷を防ぎます。大半のログはフィルタリングされるため、本番環境でも安全に利用できます。
- **信頼性**：トレースログはEMQXの全体的なメッセージスループットに影響を与えず、ログデータの保存と取得を効率的かつ信頼性高く行えます。
- **柔軟性**：メッセージやデータロスのデバッグ、クライアント切断、サブスクライブ失敗など、さまざまなシナリオで利用可能です。特定の時間に発生した問題に対しては、トレースの開始・停止を自動スケジュールしてログ収集を容易に行えます。

## ログトレースのネームスペーススコープ

EMQX 6.0.3以降、ネームスペース付きロールを使用している場合、ログトレースのアクセスはネームスペース単位でスコープされます。

- ネームスペース付きユーザーは、自身のネームスペースに属するトレースのみを`GET /trace`のレスポンスで確認できます。
- 以下のトレース単位操作は、対象トレースが異なるネームスペースに属する場合`404 Not Found`を返し、クロスネームスペースのトレース存在を漏らしません：
  - `PUT /trace/:name/stop`
  - `GET /trace/:name/download`
  - `GET /trace/:name/log`
  - `GET /trace/:name/log_detail`
  - `DELETE /trace/:name`
- 一括削除操作（`DELETE /trace`）はグローバル管理者のみが実行可能で、ネームスペース付きユーザーは`403 Forbidden`となります。

グローバル管理者はネームスペースに関係なくすべてのトレースを閲覧・管理できます。

## ログトレースの作成

このセクションでは、ダッシュボードからログトレースルールを作成する方法を説明します。クライアントID、トピック、IPアドレス、ルールIDに基づいてトレースできます。

1. 左側ナビゲーションメニューで **診断** -> **ログトレース** をクリックします。
2. **ログトレース** ページで **作成** をクリックし、トレースルールを設定します。

### 共通トレースオプションの設定

**トレース作成**ダイアログで、すべてのトレースタイプに共通する以下のオプションを設定します。

- **名前**：トレースを識別するための説明的な名前を入力します。この名前はトレース一覧に表示され、例えば「Client ID Trace」や「Topic Trace」などトレースの種類がわかる名前にすると検索や識別が容易です。
- **開始時刻 / 終了時刻**：トレースの開始・終了時刻を選択します。開始時刻が過去の場合は即時開始されます。
- **フォーマッター**：ログ出力のフォーマットを指定します。`JSON`または`Text`が選択可能です。
- **ペイロードエンコード**：トレースログ内のメッセージペイロードのフォーマットを指定します。以下から選択可能です：
  - `Text`：プレーンテキスト。JSONエンコードされたペイロードに推奨されます。
  - `HEX`：16進エンコード。カスタムバイナリプロトコルに推奨されます。
  - `Hidden`：ペイロードを`******`で隠蔽し、機密情報のマスクに有用です。
- **ペイロード制限**：トレースファイルに出力するペイロードの最大バイト数を設定します。このオプションは**ペイロードエンコード**が`Text`または`HEX`の場合のみ有効です。制限を超える場合は切り捨てられます。デフォルトは`1024 B`です。この制限はデフォルトで有効ですが、無制限に設定することも可能です。

### クライアントIDによるトレース

1. **トレース作成**ダイアログで、**タイプ**のドロップダウンリストから`Client ID`を選択します。
2. トレース対象のクライアントIDを入力します。
3. [共通トレースオプション](#共通トレースオプションの設定)を設定します。
4. **作成**をクリックします。

指定したクライアントIDとEMQXブローカー間のやり取りがログトレースされます。

### トピックによるトレース

1. **トレース作成**ダイアログで、**タイプ**のドロップダウンリストから`Topic`を選択します。
2. トレース対象のトピックを入力します。ワイルドカードもサポートされており、例：`/pay/#`。
3. [共通トレースオプション](#共通トレースオプションの設定)を設定します。
4. **作成**をクリックします。

指定したトピックにパブリッシュされたメッセージおよびサブスクライブ・アンマウントイベントがログトレースされます。

### IPアドレスによるトレース

1. **トレース作成**ダイアログで、**タイプ**のドロップダウンリストから`IP Address`を選択します。
2. トレース対象のIPアドレスを入力します。例：`192.168.0.5`。
3. [共通トレースオプション](#共通トレースオプションの設定)を設定します。
4. **作成**をクリックします。

指定したIPアドレスから接続するクライアントとEMQXブローカー間のやり取りがログトレースされます。

### ルールIDによるトレース

1. **トレース作成**ダイアログで、**タイプ**のドロップダウンリストから`Rule ID`を選択します。
2. トレース対象のルールIDを入力します。ルールIDは**データ統合** -> **ルール**ページで確認できます。
3. [共通トレースオプション](#共通トレースオプションの設定)を設定します。
4. **作成**をクリックします。

トレース結果にはルールSQLの実行結果およびルールに追加されたすべてのアクションの実行ログが含まれ、ルールのデバッグや最適化に役立ちます。

[ルールのテスト](../../develop/data-integration/rule-get-started.md#test-rules)操作はこのトレースタイプを自動的に作成・管理します。ルールをテストすると、EMQXは自動でトレースタスクを生成し、テスト停止後に自動削除します。

## ログトレースの閲覧

作成したログトレースは**ログトレース**ページに一覧表示されます。リストに表示されるログファイルサイズは非圧縮ファイルサイズの合計です。トレースは**停止**ボタンをクリックして手動で停止可能ですが、指定した終了時刻に達すると自動停止します。

作成可能なトレース数には上限があり、デフォルトは30ですが、`trace.max_traces`パラメータで変更可能です。

トレース名をクリックすると詳細画面が開き、トレースイベントの閲覧やクラスター内の特定ノードからのログダウンロードが可能です。

<img src="./assets/log-trace-node-ee.png" alt="ログトレースノード画面" style="zoom:50%;" />

デフォルトでは、各トレースはノードごとに最大128MBのログデータに制限されています。この制限は`trace.max_file_size`設定パラメータで変更可能です。ディスク容量管理のため、ファイルハンドラーはローテーション方式で動作し、トレースログがサイズ制限に達すると古いトレースイベントから順に破棄して新しいイベントの領域を確保します。これは厳密な上限ではなく、ログファイルの合計サイズは通常設定値より小さいですが、数キロバイト程度一時的に超過することがあります。

ダッシュボードからのダウンロードがタイムアウトした場合は、各EMQXノードの`/data/trace`ディレクトリから手動でトレースログを取得できます。
