# 帳票設計書 28-ThriftServerPage

## 概要

本ドキュメントは、Apache Spark Web UI における Hive ThriftServer ページ（ThriftServerPage）の帳票設計書である。JDBC/ODBC Server（Hive ThriftServer2）のセッション統計と SQL 実行統計を一覧表示する HTML レポートページの仕様を定義する。

### 本帳票の処理概要

ThriftServerPage は Hive ThriftServer2 のダッシュボードとして、サーバの起動時刻・稼働時間・オンラインセッション数・実行中SQL数の基本情報、セッション統計テーブル、SQL統計テーブルを表示する。

**業務上の目的・背景**：Hive ThriftServer は JDBC/ODBC 接続を通じて Spark SQL を利用するためのサーバコンポーネントである。複数クライアントからの接続・クエリ実行を管理するため、セッション数やSQL実行状況の監視はサーバ運用の基盤となる。本帳票により、ThriftServer の稼働状況を一元的に把握できる。

**帳票の利用シーン**：ThriftServer 稼働中に「JDBC/ODBC Server」タブを開き、接続セッションの管理やSQL実行状況を確認する際に利用される。パフォーマンス問題の検知、長時間実行クエリの特定、セッション管理に使われる。

**主要な出力内容**：
1. 基本統計（Started at、Time since start）
2. オンラインセッション数と実行中 SQL 数
3. Session Statistics テーブル（User、IP、Session ID、Start/Finish Time、Duration、Total Execute）
4. SQL Statistics テーブル（User、JobID、GroupID、Start/Finish/Close Time、Execution Time、Duration、Statement、State、Detail）

**帳票の出力タイミング**：Spark Web UI の「JDBC/ODBC Server」タブにアクセスした際にリアルタイムで生成される。

**帳票の利用者**：ThriftServer 運用管理者、DBA、データエンジニア

## 帳票種別

Web UI ページ（一覧表）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| 28 | ThriftServerPage | `/sqlserver/` | Spark UI の「JDBC/ODBC Server」タブをクリック |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | HTML（Web UI ページ） |
| 用紙サイズ | N/A（ブラウザ表示） |
| 向き | N/A |
| ファイル名 | N/A（動的 HTML レスポンス） |
| 出力方法 | ブラウザ上にリアルタイム表示 |
| 文字コード | UTF-8 |

### PDF固有設定

N/A

### Excel固有設定

N/A

## 帳票レイアウト

### レイアウト概要

```
+---------------------------------------------+
|   Spark UI ヘッダー (JDBC/ODBC Server)        |
+---------------------------------------------+
| Started at: {date}                           |
| Time since start: {duration}                 |
+---------------------------------------------+
| {N} session(s) are online, running           |
| {M} SQL statement(s)                         |
+---------------------------------------------+
| ▼ Session Statistics ({count})               |
| +------------------------------------------+|
| | User | IP | Session ID | Start Time      ||
| | Finish Time | Duration | Total Execute   ||
| +------------------------------------------+|
+---------------------------------------------+
| ▼ SQL Statistics ({count})                   |
| +------------------------------------------+|
| | User | JobID | GroupID | Start Time       ||
| | Finish Time | Close Time | Execution Time||
| | Duration | Statement | State | Detail    ||
| +------------------------------------------+|
+---------------------------------------------+
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | Started at | サーバ起動時刻 | parent.startTime | formatDate |
| 2 | Time since start | 稼働時間 | currentTime - startTime | formatDurationVerbose |
| 3 | Online sessions | オンラインセッション数 | store.getOnlineSessionNum | 数値 |
| 4 | Running SQL | 実行中 SQL 数 | store.getTotalRunning | 数値 |

### 明細部（Session Statistics）

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | User | ユーザ名 | session.userName | テキスト | auto |
| 2 | IP | クライアント IP | session.ip | テキスト | auto |
| 3 | Session ID | セッション ID | session.sessionId | リンク（セッション詳細） | auto |
| 4 | Start Time | 開始時刻 | session.startTimestamp | formatDate | auto |
| 5 | Finish Time | 終了時刻 | session.finishTimestamp | formatDate | auto |
| 6 | Duration | セッション時間 | session.totalTime | formatDurationVerbose | auto |
| 7 | Total Execute | 実行 SQL 数 | session.totalExecution | 数値 | auto |

### 明細部（SQL Statistics）

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | User | ユーザ名 | info.userName | テキスト | auto |
| 2 | JobID | Spark ジョブ ID | executionInfo.jobId | ジョブリンク | auto |
| 3 | GroupID | グループ ID | info.groupId | テキスト | auto |
| 4 | Start Time | 開始時刻 | info.startTimestamp | formatDate | auto |
| 5 | Finish Time | 終了時刻 | info.finishTimestamp | formatDate | auto |
| 6 | Close Time | クローズ時刻 | info.closeTimestamp | formatDate | auto |
| 7 | Execution Time | 実行時間 | totalTime(finishTimestamp) | formatDurationVerbose | auto |
| 8 | Duration | 全体時間 | totalTime(closeTimestamp) | formatDurationVerbose | auto |
| 9 | Statement | SQL 文 | info.statement | テキスト | auto |
| 10 | State | 実行状態 | info.state | テキスト | auto |
| 11 | Detail | 詳細情報 | info.detail / info.executePlan | エラーメッセージ | auto |

### フッター部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | ページネーション | 各テーブルのページ切り替え | PagedTable 基盤 | ページ番号リンク |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| {tag}.page | ページ番号 | No（デフォルト: 1） |
| {tag}.sort | ソートカラム名 | No（デフォルト: Start Time） |
| {tag}.desc | 降順フラグ | No |
| {tag}.pageSize | ページサイズ | No |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | Start Time（デフォルト） | 昇順（切替可能） |

### 改ページ条件

PagedTable フレームワークにより各テーブル個別にページング。

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

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| HiveThriftServer2AppStatusStore | セッション・SQL実行情報の取得 | N/A |

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

#### HiveThriftServer2AppStatusStore

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| getOnlineSessionNum | オンラインセッション数 | - | Int |
| getTotalRunning | 実行中 SQL 数 | - | Int |
| getSessionList | セッション一覧 | - | Seq[SessionInfo] |
| getExecutionList | SQL 実行一覧 | - | Seq[ExecutionInfo] |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| Duration (SQL) | executionInfo.totalTime(closeTimestamp) | なし | closeTimestamp が 0 の場合 currentTime を使用 |
| Execution Time | executionInfo.totalTime(finishTimestamp) | なし | finishTimestamp が 0 の場合 currentTime を使用 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[HTTPリクエスト受信] --> B[store.synchronized でデータ取得]
    B --> C[基本統計生成]
    C --> D[セッション統計テーブル生成]
    D --> E[SQL 統計テーブル生成]
    E --> F[headerSparkPage で HTML 生成]
    F --> G[レスポンス返却]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| テーブル描画エラー | IllegalArgumentException / IndexOutOfBoundsException | "Error while rendering job table: {exception}" | パラメータを修正する |
| データなし | セッション・SQL が空 | "No statistics have been generated yet." | クライアントが接続するまで待つ |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | セッション数十～数百、SQL 実行数百～数千 |
| 目標出力時間 | 1秒以内 |
| 同時出力数上限 | Spark Web UI のスレッドプール制約に従う |

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

- SQL Statement にはビジネスデータに関わるクエリ文が含まれるため、適切なアクセス制御が必要。
- User 名、IP アドレス等の個人情報相当の情報が表示される。
- store.synchronized でスレッドセーフなデータ取得が保証される。

## 備考

- Session ID リンクから ThriftServerSessionPage（No.29）へ遷移できる。
- SQL Statistics の Detail 列には executionInfo.detail が空の場合 executePlan が表示される。
- Finish Time と Close Time の区別：Finish Time は結果が返された時刻、Close Time はステートメントが閉じられた時刻。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SessionInfo | `sql/hive-thriftserver/src/main/scala/org/apache/spark/sql/hive/thriftserver/ui/HiveThriftServer2AppStatusStore.scala` | userName, ip, sessionId, startTimestamp, finishTimestamp, totalTime, totalExecution |
| 1-2 | ExecutionInfo | `sql/hive-thriftserver/src/main/scala/org/apache/spark/sql/hive/thriftserver/ui/HiveThriftServer2AppStatusStore.scala` | userName, groupId, statement, state, startTimestamp, finishTimestamp, closeTimestamp, jobId, detail, executePlan |
| 1-3 | SqlStatsTableRow | `sql/hive-thriftserver/src/main/scala/org/apache/spark/sql/hive/thriftserver/ui/ThriftServerPage.scala` | jobId, duration, executionTime, executionInfo, detail（行352-357） |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ThriftServerTab.scala | `sql/hive-thriftserver/src/main/scala/org/apache/spark/sql/hive/thriftserver/ui/ThriftServerTab.scala` | ページ登録（行37-38）、prefix "sqlserver" |
| 2-2 | ThriftServerPage.scala | `sql/hive-thriftserver/src/main/scala/org/apache/spark/sql/hive/thriftserver/ui/ThriftServerPage.scala` | render() メソッド（行39-53） |

**主要処理フロー**:
1. **行40**: store.synchronized でデータ一貫性を保証
2. **行41**: generateBasicStats() で基本情報生成
3. **行44-48**: オンラインセッション数・実行中SQL数の表示
4. **行50**: generateSessionStatsTable で Session テーブル生成
5. **行51**: generateSQLStatsTable で SQL テーブル生成

#### Step 3: テーブル描画を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ThriftServerPage.scala | `sql/hive-thriftserver/src/main/scala/org/apache/spark/sql/hive/thriftserver/ui/ThriftServerPage.scala` | SqlStatsPagedTable クラス（行165-278）- SQL テーブル |
| 3-2 | ThriftServerPage.scala | `sql/hive-thriftserver/src/main/scala/org/apache/spark/sql/hive/thriftserver/ui/ThriftServerPage.scala` | SessionStatsPagedTable クラス（行280-350）- Session テーブル |
| 3-3 | ThriftServerPage.scala | `sql/hive-thriftserver/src/main/scala/org/apache/spark/sql/hive/thriftserver/ui/ThriftServerPage.scala` | SqlStatsTableDataSource（行359-407）, SessionStatsTableDataSource（行409-442） |

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

```
SparkUI
    |
    +-- ThriftServerTab (SparkUITab, prefix="sqlserver")
           |
           +-- ThriftServerPage (WebUIPage, prefix="")
           |      |
           |      +-- render(request) [store.synchronized]
           |             +-- generateBasicStats()
           |             +-- store.getOnlineSessionNum
           |             +-- store.getTotalRunning
           |             +-- generateSessionStatsTable()
           |             |      +-- SessionStatsPagedTable
           |             |             +-- SessionStatsTableDataSource
           |             +-- generateSQLStatsTable()
           |                    +-- SqlStatsPagedTable
           |                           +-- SqlStatsTableDataSource
           |
           +-- ThriftServerSessionPage (No.29)
```

### データフロー図

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

HTTPリクエスト                   render()
                            --> store.synchronized          --> HTML レスポンス
                                 |                            (基本情報 +
HiveThriftServer2AppStatusStore  |                             Session テーブル +
(インメモリ)                --> getSessionList                  SQL テーブル)
                                 getExecutionList
                                 getOnlineSessionNum
                                 getTotalRunning
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ThriftServerPage.scala | `sql/hive-thriftserver/src/main/scala/org/apache/spark/sql/hive/thriftserver/ui/ThriftServerPage.scala` | ソース | メインページクラス |
| ThriftServerTab.scala | `sql/hive-thriftserver/src/main/scala/org/apache/spark/sql/hive/thriftserver/ui/ThriftServerTab.scala` | ソース | タブ登録 |
| HiveThriftServer2AppStatusStore.scala | `sql/hive-thriftserver/src/main/scala/org/apache/spark/sql/hive/thriftserver/ui/HiveThriftServer2AppStatusStore.scala` | ソース | データストア |
| ToolTips.scala | `sql/hive-thriftserver/src/main/scala/org/apache/spark/sql/hive/thriftserver/ui/ToolTips.scala` | ソース | ツールチップ文言定義 |
| ThriftServerSessionPage.scala | `sql/hive-thriftserver/src/main/scala/org/apache/spark/sql/hive/thriftserver/ui/ThriftServerSessionPage.scala` | ソース | セッション詳細（リンク先、No.29） |
