# コンソール

> 動いているプログラムの実時間の診断の流れ。記憶の中の 500 件を、レベル、領域、コンポーネントで検索して絞り込みます。切り分けのための詳細記録とサポートパッケージも付きます。

[イベント](events)のコンソールのタブ（`/events?view=console`）は、プログラム全体の診断の流れです。どの下位の仕組み（アプリ、組み込みの OPC UA サーバー、ドライバー、Logic、Process、ダッシュボード、エージェントアクセス、ライセンス）も 1 本の流れに書き込み、コンソールはその直近 500 件を実時間で見せます。最後のタブなのは、型どおりの時系列のあとで最後に読む技術的な細部だからです。見るには**イベントの表示**が要り、行を書き出したりサポートパッケージを作ったりするには**履歴のエクスポートとインポート**が要り、詳細記録を始めたり止めたりするには**設定の変更**が要ります。

## 流れとそのバッファー {#the-feed-and-its-buffer}

コンソールは、プロセスの唯一の診断の流れを記憶の中に映したものです。新しい方から 500 件で、それを見せるすべての面（ステーション自身のウィンドウ、どの離れたブラウザーも、どのタブも）が共有します。新しいものが来ると古いものは落ちていき、このタブのものは再起動を生き延びません。同じ流れは日ごとに切り替わるファイルにも書かれます。ステーションのデータのフォルダーの `logs\ganter-lab-<date>.log` で（30 日分を保ち、1 ファイル 50 MB です）、サポートパッケージが集めるのはこれです。

どのエントリも、コンソールやファイルに届く前に伏せ字にされます。URL の中のパスワード、トークン、鍵、資格情報は「[REDACTED]」に、プロトコルの中身（生のバイト、JSON や XML の文書）は「[PROTOCOL PAYLOAD OMITTED]」に置き換わり、メッセージは 16 KB、例外は 64 KB で「…[TRUNCATED]」を付けて切られます。流れに入るのは情報のレベル以上のものだけです。細かすぎる内容と、作り手が診断の細部（生の、繰り返しの多いプロトコルのやり取り）と印を付けたエントリは、詳細記録のファイルにだけ届きます。繰り返す通信の失敗は、作り手のところで最初の失敗の行、定期的な要約、回復の行にまとめられるので、壊れた機器が一覧をあふれさせることはありません。

## 1 つのエントリ {#an-entry}

どの行も、時刻、レベルを表す点（情報には中立、警告には注意、エラーには重大）、「領域 · コンポーネント」、そしてメッセージを見せます。行の右端の**行をコピー**のボタンは「完全な時刻 [重大度] 領域 · コンポーネント メッセージ」をコピーし、操作ログ帯が「行をクリップボードにコピーしました。」と答えます（クリップボードを渡さないブラウザーでは「クリップボードがコピーを受け付けませんでした。」）。行を押すとそれが選ばれ、詳細のパネルが開きます。

## 検索 {#search}

「メッセージと、得られるすべての文脈を検索」の入力欄が、間を置かずに入力しながら絞り込みます。メッセージ、領域、コンポーネント、ロガー、機器、タグ、操作、クライアント、セッション、ユニット、手順、実行記録の識別子、細部の文字（例外とその呼び出しの跡）のどれかに、その文字が（大文字と小文字を区別せずに）含まれていれば、その行は一致します。

## レベルのチップ {#the-level-chips}

**情報**、**警告**、**エラー**の 3 つのチップは、それぞれレベルの色合いの点と実時間の数を持つ切り替えです。入っているチップは自分のレベルを見せます。押すと、そのレベルを隠します。数は、今の検索、領域、コンポーネントのもとでそのチップが現すことになる件数です。その 3 つの絞り込みは尊重し、レベルの切り替えそのものは無視するので、隠したレベルも自分が抱えているものを知らせ続けます。3 つとも入った状態で始まります。

デバッグのチップはありません。情報より下のエントリは流れに入らないので、そのためのチップはいつも 0 としか読めず、何も隠せないからです。細かすぎる内容は、代わりに詳細記録のファイルで見つけます。

## 領域とコンポーネントの一覧 {#the-area-and-component-lists}

| 一覧 | 値 | 何をするか |
| --- | --- | --- |
| 領域 | **すべての領域**（既定）、続いて下位の仕組みごとに **App**、**Server**、**Connector**、**Logic**、**Process**、**Dashboard**、**Agent**、**Licensing** | 1 つの下位の仕組みのエントリを残します。 |
| コンポーネント | **すべてのコンポーネント**（既定）、続いて選んだ領域についてバッファーにある全コンポーネントを、五十音と英字の順で | 領域の中の 1 つの具体的な作り手（あるドライバー、あるワーカー、OPC UA の SDK）のエントリを残します。 |

| 領域 | そこに何が書くか |
| --- | --- |
| App | アプリケーションの一生です。デスクトップのホスト、ログ、異常終了と更新の扱い、イベントの記録簿自身の失敗、そして、ほかの領域を名乗らなかったものすべてです。 |
| Server | 組み込みの OPC UA サーバーと、その SDK です。 |
| Connector | 機器との通信です。コネクター、ドライバー、タグの読み書きです。 |
| Logic | 変数、アクション、トリガー、警報、そして書き込みの経路です。 |
| Process | モデル、レシピ、判定、発生記録、インターロックの監視、そして実行の一生です。 |
| Dashboard | ダッシュボードで押された指令と、それを配る組み込みのウェブのホストです。 |
| Agent | AI のエージェントが MCP を通して行ったことです。 |
| Licensing | ステーションのライセンスと、ライセンスのないランタイムの制限です。 |

選んだコンポーネントは、それを持つエントリがすべてバッファーから流れ出たあとも一覧に残るので、1 つのドライバーを見張るように置いた絞り込みが、黙ってすべてのコンポーネントへ広がることはありません。そのときは空の一覧が、正直な答えです。領域を変えると、その領域についてコンポーネントの一覧が作り直されます。

## 末尾への追従 {#following-the-tail}

**末尾に追従（自動スクロール）**が入っていると（既定です）、一覧は流れが伸びるにつれて新しいエントリに貼り付きます。上へたどると外れるので、エントリが届き続ける間に何かを読めます。いちばん下から 24 ピクセル以内まで戻ると、また入ります。外れている間は、今の絞り込みに一致した到着の数を「新しいエントリ N 件」（または「新しいエントリ 1 件」）のピルが数えます。それか、ツールバーのボタンを押すと、末尾へ戻ります。別のタブへ移って戻っても追従の状態は残り、入っていたなら末尾へ跳びます。

## ツールバー {#the-toolbar}

| 指令 | 何をするか | 灰色になるとき | 描かれないとき |
| --- | --- | --- | --- |
| 記録を開始 / 記録を停止 | 詳細な診断の記録を最大 15 分間始めるか、動いているものを止めます（下を参照）。 | 切り替えを適用している間 | ロールが設定の変更を持たないとき |
| 別のウィンドウで開く | イベントのページを、ブラウザーの新しいタブかウィンドウで開きます。ステーション自身のウィンドウでも離れたブラウザーでも同じなので、流れを 2 台目の画面に置いておけます。新しいウィンドウは、このボタンが載っているコンソールのタブで開きます。ポップアップを塞ぐブラウザーでは何も開かず、操作ログ帯がそう伝えます。「ブラウザーが 2 つ目のウィンドウを開きませんでした。このステーションのポップアップを許可してから、やり直してください。」 | | |
| 折り返し | 長いメッセージを切り詰める代わりに、何行かに折り返します。 | | |
| 末尾に追従（自動スクロール） | 追従を入れる（末尾へ跳び、新しいエントリの数を消します）か、外します。 | | |
| 表示を消去 | 記憶の中の流れを、すべての面で一度に空にします。ステーションのウィンドウも、どの離れたブラウザーも、どのタブも、同じ空の一覧を見ます。操作ログ帯は「ステーション全体で、コンソールの表示を消去しました。」と答えます。切り替わるログのファイル、記録のファイル、イベントの記録簿には手を触れません。 | ランタイムが停止しているとき。ボタンは灰色になり、ツールチップが、ステーションは今どんな変更も受け付けないと伝えます | ロールが設定の変更を持たないとき |
| エクスポート | メニューを開きます。**CSV で書き出す…**、**JSON で書き出す…**、そして区切りのあとに**サポートパッケージを作成…**です。 | サポートパッケージを作成は、1 つが組み立てられている間は灰色になります | ロールが履歴のエクスポートとインポートを持たないとき |

## 詳細記録 {#detailed-capture}

**記録を開始**は、プロセスの全体を最大 15 分間、細かいログの段階に上げ、細かすぎる内容もプロトコルのやり取りも含めてすべてを、それ自身の記録のファイルに書きます。ステーションのデータのフォルダーの `logs\diagnostic-captures\ganter-temporary-diagnostic-<stamp>-<id>.log` です（1 回の記録は 25 MB で切り替わり、2 ファイルを保ちます。直近 10 回分が残ります）。500 件の流れと、通常の切り替わるファイルはそのままです。そこに余分なものは届きません。

そのあとボタンは**記録を停止**と読めます。ツールチップは「詳細な診断の記録を早めに止めます。開始 hh:mm:ss。」と言います。記録は、残り時間が 0 になったとき、ボタンを押したとき、アプリが終わるときに、自分で止まります。始まりと終わりのどちらも操作ログ帯に告げられ（「最大 15 分間、詳細記録を開始しました。」、「詳細記録を停止しました。」）、App · Diagnostic capture の下にコンソールの行を残します。

この記録はステーション全体の切り替えです。どの回線も同じ残り時間を見て、押したウィンドウより長生きします。だからこそ**設定の変更**が要ります。それを持たないロールにはボタンが描かれず、それでも処理に届いた押下には「詳細記録の開始と停止には「設定の変更」の権限が必要です。」と答えます。記録が何をしているかは、どの権限にも縛られません。記録が動いている間は、ボタンの隣の表示が、記録中を示す点と「詳細記録は実行中」、そして残り時間（15:00 からの mm:ss）を出し、どのロールもそれを読めます。何も記録していないときは、同じ表示が読み上げだけになり、「詳細記録は停止中」と読み上げます。

## サポートパッケージを作成 {#create-support-package}

エクスポートのメニューの最後の項目は、サポートに渡す zip を組み立て、ブラウザーを通してダウンロードします。操作ログ帯は「サポートパッケージを作成しました：」に続けてファイル名（`ganter-support-<stamp>-<id>.zip`）を答えるか、「サポートパッケージの作成に失敗しました：」に続けて理由を答えます。ほかのエクスポートと同じく**履歴のエクスポートとインポート**が要ります。パッケージが持つものは次のとおりです。

| 項目 | 内容 |
| --- | --- |
| `recent-console.json` | 記憶の中の流れのエントリを、構造化した記録として収めます（絞り込んだ表示ではなく、どのエントリのどの項目もです）。 |
| `logs/ganter-lab-*.log` | 通常の切り替わるログのファイルです。 |
| `diagnostic-captures/ganter-temporary-diagnostic-*.log` | 詳細記録のファイルです。 |
| `manifest.json` | いつ作られたか、記録の状態（動作中、開始、終了予定、停止、ファイル名）、流れのエントリを何件入れたか、上限、大きさを添えた同梱ファイルの一覧、そして省いたものとその理由のすべてです。 |

ファイルは、予算の中で新しい方から取ります。最大 8 ファイル、1 ファイル最大 24 MB、合計 96 MB です。取り分より大きいファイルは末尾だけ（新しい方のバイトだけ）を入れ、目録がそう言います。zip はシステムの一時のフォルダーで組み立てられ、ダウンロードを渡し終えると削除されます。

## 詳細のパネル {#the-detail-panel}

エントリを選ぶと、重大度のバッジ、「領域 · コンポーネント」、閉じる十字を持つパネルが開き、続いて次のものが並びます。

| 節 | 項目 | 内容 |
| --- | --- | --- |
| 見出し | 時刻 | ミリ秒までの完全な日付と時刻です。 |
| 見出し | メッセージ | 1 行のメッセージです。 |
| 文脈 | 領域 | 下位の仕組みです。 |
| 文脈 | コンポーネント | 具体的な作り手です。 |
| 文脈 | ロガー | そのエントリの背後にあるロガーの分類で、分かるときに出ます。 |
| 文脈 | レベル | そのレベルのチップの言葉で、情報、警告、エラーのいずれかです。デバッグは出ません。情報より下のエントリは流れに入らないからです。 |
| 文脈 | 機器、タグ、操作、クライアント、セッション、ユニット、手順、実行記録 | そのエントリが持つときだけ出ます。コネクターの行が指す機器とタグ、診断している操作（読み取り、書き込み、接続）、OPC やプロトコルのクライアントとセッション、そして Process のユニット、手順、実行記録の識別子です。 |
| 詳細 | | そのエントリが持っていたときの、例外の文字と呼び出しの跡です。 |

下の**エントリをコピー**は、パネルの全体を文字としてコピーし（見出しの行、メッセージ、文脈の項目ごとに「名前：値」の 1 行、そして細部のかたまり）、「エントリをクリップボードにコピーしました。」と答えます。エントリがバッファーから流れ出ると選択は外れ、表示を消去でも消えます。

## エクスポート {#export}

**CSV で書き出す…**と **JSON で書き出す…**は、今見えている行（絞り込んだ表示）を、`app-logs-<yyyyMMdd-HHmmss>.csv` または `.json` という名前のブラウザーのダウンロードとして書きます。操作ログ帯は「N 行を書き出しました」に続けてファイル名を答えます。どちらも同じ列をこの順に持ちます。`Timestamp`（CSV では「Timestamp (UTC-03:00)」という見出しで、時刻の基準を一度だけ明示します）、`Severity`、`Area`、`Component`、`Logger`、`Device`、`Tag`、`Operation`、`Client`、`Session`、`Unit`、`Procedure`、`RunId`、`Message`、`Exception` です。JSON は包みで、`{ "TimeZone": "...", "Entries": [ ... ] }` です。`=`、`+`、`-`、`@` で始まる CSV のます目には、表計算がそれを文字として読むよう、アポストロフィーを前に付けます。

## 状態の行 {#the-status-line}

「表示 N 件 · バッファ内 M 件」と読め、検索、領域、コンポーネント、レベルのどれかの絞り込みが効いている間は「 · 絞り込みあり」が続きます。右側には、エントリを選んでいる間の「1 件を選択中」と、バッファ内でいちばん新しいエントリの時刻を示す「更新 hh:mm:ss」が、ページを開いた時点から出ます。何も一致しないとき、一覧は「いまの絞り込みに合うエントリはありません。レベル、領域、コンポーネント、検索の語を変えると、もっと表示されます。」と読めます。

## コンソールがしないこと {#what-console-does-not-do}

- これは記録ではありません。記憶の中に 500 件を持ち、再起動で失い、表示を消去は全員のためにそれを空にします。永続する記録は 3 つの時系列であり、ディスクの上では切り替わるログのファイルです。
- 情報より下は何も見せず、プロトコルの細部も決して見せません。それは詳細記録のためのものです。
- 表示を消去はファイルも記録簿の行も削除せず、ランタイムが停止している間は拒まれ、その隣のエクスポートや記録を開始と同じく、設定を変えてよいロールにだけ描かれます。
- 詳細記録を 15 分より長くすることはできません。もう 1 回始めてください。
- エクスポートは見えているものを書くのであって、ディスクの上のファイルを書くことは決してありません。ファイルがステーションから出ていく道は、サポートパッケージです。
- ログの範囲を開いたエージェントは、`logs_read` を通して同じ流れを読みます（[ツール](agent-tools)を参照）。エージェントがそれを消去することはできません。
