# 帳票設計書 17-Tasks Report

## 概要

本ドキュメントは、OpenSearchのCat API「/_cat/tasks」エンドポイントが出力するTasks Reportの設計仕様を定義する。本帳票はクラスタで現在実行中のタスク情報をテキストテーブル形式にて出力するものである。

### 本帳票の処理概要

本帳票は、OpenSearchクラスタ内で実行中のタスク（インデックス操作、検索、管理操作等）の詳細情報を一覧化する。タスクは親子関係を持つことがあり、TaskGroupとして階層的にソートされて出力される。オプションのdetailedモードではタスクの説明やリソース消費情報も表示される。

**業務上の目的・背景**：長時間実行されるタスクやリソースを大量に消費するタスクの把握は、クラスタのパフォーマンス管理において重要である。本帳票により現在実行中のタスクを可視化し、問題のあるタスクの特定・キャンセルの判断材料を提供する。

**帳票の利用シーン**：長時間実行タスクの監視、reindex等の重い操作の進捗確認、リソース消費の把握、タスクキャンセル前の情報確認に利用される。

**主要な出力内容**：
1. タスク識別情報（ID、タスクID、親タスクID、タイプ、アクション）
2. 時間情報（開始時刻、実行時間）
3. ノード情報（ノードID、IP、ポート、ノード名、バージョン）
4. X-Opaque-ID
5. 詳細情報（description、resource_stats）- detailedモード時

**帳票の出力タイミング**：ユーザーがREST APIエンドポイント `GET /_cat/tasks` にHTTPリクエストを送信した際にリアルタイムで生成・出力される。

**帳票の利用者**：OpenSearchクラスタ管理者、SRE、パフォーマンス監視担当者。

## 帳票種別

一覧表（実行中タスク一覧）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | REST API | `GET /_cat/tasks` | HTTPリクエスト送信 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | text/plain（テキストテーブル）またはJSON/YAML（format指定時） |
| 用紙サイズ | N/A（API応答） |
| 向き | N/A |
| ファイル名 | N/A（HTTPレスポンスボディ） |
| 出力方法 | HTTPレスポンス |
| 文字コード | UTF-8 |

### PDF固有設定

該当なし

### Excel固有設定

該当なし

## 帳票レイアウト

### レイアウト概要

テキストテーブル形式で、1行が1タスクに対応する一覧を出力する。タスクグループ単位で開始時刻順にソートされ、親タスク→子タスクの順で出力される。

```
┌──────────────────────────────────────────────────────────────┐
│  ヘッダー部（action, task_id, parent_task_id, type,           │
│  start_time, timestamp, running_time, ip, node 等）           │
├──────────────────────────────────────────────────────────────┤
│  明細部（タスクごとに1行、階層的にソート）                       │
│  例: indices:data/write/bulk  abc123:456  -  transport        │
│      10:30:00  1.2s  10.0.0.1  node1                         │
└──────────────────────────────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | id | タスクID数値（デフォルト非表示） | TaskInfo.getId() | 数値 |
| 2 | action | タスクアクション名 | TaskInfo.getAction() | 文字列（alias: ac） |
| 3 | task_id | タスクID（ノード:ID形式） | TaskInfo.getTaskId().toString() | 文字列（alias: ti） |
| 4 | parent_task_id | 親タスクID | TaskInfo.getParentTaskId() | 文字列、未設定時"-"（alias: pti） |
| 5 | type | タスクタイプ | TaskInfo.getType() | 文字列（alias: ty） |
| 6 | start_time | 開始時刻（ms） | TaskInfo.getStartTime() | ミリ秒（alias: start） |
| 7 | timestamp | 開始時刻（HH:MM:SS） | TaskInfo.getStartTime() | HH:mm:ss形式（alias: ts, hms） |
| 8 | running_time_ns | 実行時間（ns、デフォルト非表示） | TaskInfo.getRunningTimeNanos() | ナノ秒 |
| 9 | running_time | 実行時間（人間可読） | TaskInfo.getRunningTimeNanos() | TimeValue形式 |
| 10 | node_id | ノードID（デフォルト非表示） | TaskInfo.getTaskId().getNodeId() | 文字列（alias: ni） |
| 11 | ip | IPアドレス | DiscoveryNode.getHostAddress() | 文字列（alias: i） |
| 12 | port | ポート（デフォルト非表示） | DiscoveryNode.getAddress().address().getPort() | 数値（alias: po） |
| 13 | node | ノード名 | DiscoveryNode.getName() | 文字列（alias: n） |
| 14 | version | バージョン（デフォルト非表示） | DiscoveryNode.getVersion() | 文字列（alias: v） |
| 15 | x_opaque_id | X-Opaque-ID（デフォルト非表示） | TaskInfo.getHeaders().get(X_OPAQUE_ID) | 文字列（alias: x） |
| 16 | description | タスク説明（detailed時のみ） | TaskInfo.getDescription() | 文字列（alias: desc） |
| 17 | resource_stats | リソース統計（detailed時のみ、デフォルト非表示） | TaskInfo.getResourceStats() | 文字列 |

### 明細部

上記ヘッダー部と同一構成。

### フッター部

フッター部は存在しない。

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| detailed | 詳細モード（description, resource_stats追加） | No（デフォルト: false） |
| full_id | ノードIDフル表示 | No（デフォルト: false） |
| ListTasksRequestの各パラメータ | generateListTasksRequestから生成 | No |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | タスクグループ | startTime昇順（行190: Comparator.comparingLong） |
| 2 | 子タスク | 再帰的にstartTime昇順 |

### 改ページ条件

改ページなし。

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| ListTasksResponse（内部API） | タスク情報取得 | ListTasksRequest |
| DiscoveryNodes（内部API） | ノード名前解決 | nodesInCluster supplier |

### テーブル別参照項目詳細

#### ListTasksResponse

| 参照項目 | 帳票項目との対応 | 取得条件 | 備考 |
|---------|----------------|---------|------|
| TaskInfo.getId() | id | - | タスクID数値 |
| TaskInfo.getAction() | action | - | アクション名 |
| TaskInfo.getTaskId() | task_id | - | ノードID:タスクID形式 |
| TaskInfo.getParentTaskId() | parent_task_id | isSet()で判定 | 未設定時"-" |
| TaskInfo.getType() | type | - | transport等 |
| TaskInfo.getStartTime() | start_time, timestamp | - | ミリ秒 |
| TaskInfo.getRunningTimeNanos() | running_time_ns, running_time | - | ナノ秒 |
| TaskInfo.getDescription() | description | detailed=true時 | タスク説明 |
| TaskInfo.getResourceStats() | resource_stats | detailed=true時 | リソース統計 |
| TaskInfo.getHeaders() | x_opaque_id | X_OPAQUE_IDキー | デフォルト"-" |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| timestamp | FORMATTER.format(Instant.ofEpochMilli(startTime)) | - | HH:mm:ss(UTC) |
| running_time | TimeValue.timeValueNanos(runningTimeNanos) | - | 人間可読形式 |
| node_id（短縮） | Strings.substring(nodeId, 0, 4) | - | full_id=false時 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[クライアントからGETリクエスト受信] --> B[RestTasksAction.doCatRequest]
    B --> C[generateListTasksRequest呼出]
    C --> D[NodeClient.admin.cluster.listTasks実行]
    D --> E[ListTasksResponse受信]
    E --> F[buildTable: getTaskGroups取得]
    F --> G[buildGroups: TaskGroupを開始時刻でソート]
    G --> H[buildRow: 各タスクの行を構築]
    H --> I{子タスクあり?}
    I -->|Yes| G
    I -->|No| J[RestTable.buildResponse]
    J --> K[HTTPレスポンス返却]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| ノード離脱 | タスク実行ノードがレスポンス後に離脱 | IP/ポート/名前/バージョンが"-"出力（行174-177） | DiscoveryNodes.get()がnull時のガード |
| タスクなし | 実行中タスクがない場合 | 空テーブル | 正常動作 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 実行中タスク数（通常数個〜数百個） |
| 目標出力時間 | 全ノードからのタスク収集に依存（通常1秒以内） |
| 同時出力数上限 | REST APIスレッドプールに依存 |

## セキュリティ考慮事項

タスク情報にはクエリ内容等が含まれる可能性があるため、cluster:monitor/tasks/lists 権限を持つユーザーのみアクセス可能とすべきである。

## 備考

- タスクは親子関係を持つ階層構造（TaskGroup）として管理される
- buildGroups()は再帰的に子タスクも処理（行187-195）
- `detailed` パラメータは追加のレスポンスパラメータとして登録（行103-115）
- `generateListTasksRequest` は RestListTasksAction のstaticメソッドを使用（行94）
- コンストラクタで `Supplier<DiscoveryNodes>` を受け取り、ノード名前解決に使用

---

## コードリーディングガイド

本帳票を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | TaskInfo.java | `server/src/main/java/org/opensearch/tasks/TaskInfo.java` | タスク情報の全フィールド（action, type, startTime, runningTimeNanos等） |
| 1-2 | TaskGroup.java | `server/src/main/java/org/opensearch/action/admin/cluster/node/tasks/list/TaskGroup.java` | 親子タスクのグループ構造。getTaskInfo()とgetChildTasks() |
| 1-3 | ListTasksResponse.java | `server/src/main/java/org/opensearch/action/admin/cluster/node/tasks/list/ListTasksResponse.java` | getTaskGroups()メソッド |

**読解のコツ**: TaskGroupは木構造で、buildGroups()メソッドが再帰的に子タスクを処理する点が重要。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestTasksAction.java | `server/src/main/java/org/opensearch/rest/action/cat/RestTasksAction.java` | 帳票メインクラス。204行 |

**主要処理フロー**:
1. **行73-75**: コンストラクタでnodesInCluster supplierを受け取る
2. **行93-101**: doCatRequest()でgenerateListTasksRequestを呼出しListTasksを実行
3. **行118-149**: getTableWithHeader()でdetailedパラメータに応じて15-17カラム定義
4. **行153-185**: buildRow()で1タスクの行を構築。ノード離脱への安全なガード処理
5. **行187-195**: buildGroups()で再帰的にTaskGroupを処理。startTime昇順ソート
6. **行197-203**: buildTable()でbuildGroupsを呼出

#### Step 3: リクエスト生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | RestListTasksAction.java | `server/src/main/java/org/opensearch/rest/action/admin/cluster/RestListTasksAction.java` | generateListTasksRequest() staticメソッド |

### プログラム呼び出し階層図

```
HTTP GET /_cat/tasks
    |
    +-- AbstractCatAction.prepareRequest()
        |
        +-- RestTasksAction.doCatRequest() [行93]
            |
            +-- RestListTasksAction.generateListTasksRequest() [行94]
            +-- NodeClient.admin().cluster().listTasks() [行95]
                |
                +-- RestResponseListener.buildResponse() [行97]
                    |
                    +-- buildTable() [行197]
                        |
                        +-- buildGroups() [行187] (再帰)
                            |
                            +-- sortedGroups.sort(startTime) [行190]
                            +-- buildRow() [行153] x N
                            |   +-- DiscoveryNodes.get(nodeId) [行156]
                            |   +-- table.addCell() x 15-17 [行158-183]
                            +-- buildGroups(childTasks) [行193] (再帰)
```

### データフロー図

```
[入力]                    [処理]                           [出力]

HTTP GET Request   --> RestTasksAction                  --> HTTP Response
  /_cat/tasks           |                                   (text/plain
  ?detailed=true        +-> ListTasksRequest                 or JSON)
                        +-> ListTasksResponse
                        |   (TaskGroup[] - 階層構造)
                        +-> nodesInCluster supplier
                        |   (DiscoveryNodes for name resolve)
                        +-> buildGroups() (再帰)
                        +-> buildRow() per task
                        +-> RestTable.buildResponse()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestTasksAction.java | `server/src/main/java/org/opensearch/rest/action/cat/RestTasksAction.java` | ソース | 帳票メインクラス（204行） |
| AbstractCatAction.java | `server/src/main/java/org/opensearch/rest/action/cat/AbstractCatAction.java` | ソース | Cat API基底クラス |
| RestTable.java | `server/src/main/java/org/opensearch/rest/action/cat/RestTable.java` | ソース | テーブルレスポンス構築 |
| TaskInfo.java | `server/src/main/java/org/opensearch/tasks/TaskInfo.java` | ソース | タスク情報 |
| TaskGroup.java | `server/src/main/java/org/opensearch/action/admin/cluster/node/tasks/list/TaskGroup.java` | ソース | タスクグループ（階層構造） |
| ListTasksRequest.java | `server/src/main/java/org/opensearch/action/admin/cluster/node/tasks/list/ListTasksRequest.java` | ソース | タスク一覧リクエスト |
| ListTasksResponse.java | `server/src/main/java/org/opensearch/action/admin/cluster/node/tasks/list/ListTasksResponse.java` | ソース | タスク一覧レスポンス |
| RestListTasksAction.java | `server/src/main/java/org/opensearch/rest/action/admin/cluster/RestListTasksAction.java` | ソース | generateListTasksRequest()メソッド |
| Task.java | `server/src/main/java/org/opensearch/tasks/Task.java` | ソース | X_OPAQUE_ID定数 |
| RestTasksActionTests.java | `server/src/test/java/org/opensearch/rest/action/cat/RestTasksActionTests.java` | テスト | テストケース |
| ActionModule.java | `server/src/main/java/org/opensearch/action/ActionModule.java` | ソース | アクション登録 |
