[Work 031] Geminiに正規表現のパース変換を手伝ってもらう【プロンプトログ】
* **JSch**
JavaプログラムからSSH接続を行い、リモートサーバー操作を可能にするライブラリのこと。
* **正規表現 (Regex)**
文字列のパターンを記号で表現する手法。今回は「2つ以上の連続する空白」の検出に使用された。
* **nvidia-smi**
NVIDIA製GPUの稼働状況や温度、メモリ使用量などを確認・管理するためのコマンドツール。
* **rocm-smi**
AMD製GPU向けのシステム管理ツール。NVIDIAのsmi同様、GPUの詳細情報を表示する。
* **Ollama**
大規模言語モデル(LLM)をローカル環境で簡単に実行・管理するためのプラットフォーム。
# Work031-Java SSH Monitoring
## Turn 1
### User
> このクラスは私が作ったものです。
>
> docker psのコマンドで返ってくる文字列をパースしてpublic List<ContainerInfo> containerInfoList;の配列に格納しています。
>
> ```docker ps
> # docker ps の出力結果
> ・・・省略・・・
> ```
### Gemini
Work030.md
[[DATE/TIME]] Java SSH Docker Monitoring: Parsing docker ps
Tag: [[Java]], [[SSH]], [[Docker]], [[JSch]], [[Regex]]
1. 目的
- AIサーバー運用の自動化: Node B (EVO-X2) 上で稼働する多数のDockerコンテナ(Ollama, WebUI, Wiki等)の状態を、外部のJavaプログラムからSSH経由で監視・把握する。
- CLI出力の構造化: docker ps コマンドのテキスト出力を、Javaオブジェクト (ContainerInfo) のリストへ正確に変換するパーサーを実装する。
- 不規則なフォーマットへの対応: カラム内の空白("Up [DATE/TIME]" 等)や、任意項目(PORTS)の有無による列ズレ問題を解決する。
2. システム環境
- Controller: Java Custom App (OpenJDK 21)
- Target Node: Node B (EVO-X2 / Ubuntu Native)
- Library: com.jcraft.jsch (SSH Client)
- Target Command: docker ps (Standard Output)
3. 作業ログ・解決プロセス
発生した課題
- 単純なスペース区切りの限界:docker ps の出力には、STATUS カラム(例: Up [DATE/TIME])や COMMAND カラム(例: "/sbin/tini -- /usr/…")のように、値の中にスペースが含まれるフィールドがある。String.split(" ") ではこれらも分割されてしまい、カラム位置がずれて正しくパースできない。
- docker ps の出力には、STATUS カラム(例: Up [DATE/TIME])や COMMAND カラム(例: "/sbin/tini -- /usr/…")のように、値の中にスペースが含まれるフィールドがある。
- String.split(" ") ではこれらも分割されてしまい、カラム位置がずれて正しくパースできない。
- 可変カラム (PORTS):コンテナによっては PORTS 情報が存在しない(ホストネットワーク使用時や公開ポートなし)場合があり、その行だけカラム数が減ってしまう。
- コンテナによっては PORTS 情報が存在しない(ホストネットワーク使用時や公開ポートなし)場合があり、その行だけカラム数が減ってしまう。
解決策・決定打
- 正規表現による区切り (\\s{2,}):docker ps の出力フォーマットが「カラム間は広い空白(2文字以上)で区切られている」特性に着目。区切り文字を 「2つ以上の連続する空白」 と定義することで、値の中にある単一スペース(Up [DATE/TIME])を無視してカラム単位で分割することに成功。
- docker ps の出力フォーマットが「カラム間は広い空白(2文字以上)で区切られている」特性に着目。
- 区切り文字を 「2つ以上の連続する空白」 と定義することで、値の中にある単一スペース(Up [DATE/TIME])を無視してカラム単位で分割することに成功。
- 可変長の判定ロジック:分割後の配列サイズ (parts.length) をチェックし、要素数が 7 なら全カラムあり、それ未満なら PORTS が空であると判定してマッピングを動的に変更するロジックを実装。
- 分割後の配列サイズ (parts.length) をチェックし、要素数が 7 なら全カラムあり、それ未満なら PORTS が空であると判定してマッピングを動的に変更するロジックを実装。
4. 成果物 (Implementation)
Java Class: CmdDockerPs.java
```java
// Javaソースコード(CmdDockerPsクラス)
・・・省略・・・
```
解析対象データ例 (Docker PS Output)
```text
# 解析対象データ例
・・・省略・・・
```
上記の通り、STATUS カラム等のスペース混じりの値も、正規表現 \s{2,} により正しく1つのフィールドとして認識される。
5. 今後の展望
- ヘルスチェック統合: STATUS フィールドに含まれる (healthy) や (unhealthy) の文字列を解析し、異常検知時にアラートを飛ばすロジックを追加する。
- リソース監視: docker stats コマンドのパーサーも同様の手法で実装し、CPU/メモリ使用率の追跡を可能にする。
---
## Turn 2
### User
> このクラスを参考に、ollama psの結果を配列にして返すように変更してください。
> ```text
> [MASKED_DATA]:~$ docker exec -it ollama-cuda ollama ps
> # ollama ps の出力結果
> ・・・省略・・・
> ```
### Gemini
CmdDockerPs.java を参考に、ollama ps コマンドの出力をパースする CmdOllamaPs クラスを作成しました。
変更・実装のポイント:
- コマンドの変更: execCmd メソッド内のコマンドを docker exec ollama-cuda ollama ps に変更しました(SSH経由での自動処理用として、TTY制御コードが入らないよう -it オプションは除外するのが一般的です)。
- 正規表現の維持: ollama ps の出力もカラム間が広い空白で、値の中(例: 1.2 GB, 4 minutes from now)に単一スペースが含まれる形式のため、CmdDockerPs と同様に \\s{2,}(2つ以上の連続する空白)での分割が有効です。
- データ構造の変更: 内部クラスを ContainerInfo から OllamaModelInfo に変更し、NAME, ID, SIZE, PROCESSOR, CONTEXT, UNTIL の6項目を保持するようにしました。
```java
// Javaソースコード(CmdOllamaPsクラス)
・・・省略・・・
```
---
## Turn 3
### User
> 完璧です。さすがGemini。
>
> では、次です。
> 同じ要領で、nvidia-smiの結果をパースしてください。
>
> これは配列情報ではないので、Listにする必要はありません。
> 監視する上で必要だと思われるスコア(GPU使用率、消費電力、VRAM使用量、VRAM容量)などをいい感じに取得してください。
>
> ```text
> [MASKED_DATA]:~$ nvidia-smi
> [DATE/TIME]
> # nvidia-smi の出力結果
> ・・・省略・・・
> ```
### Gemini
nvidia-smi の出力結果をパースする CmdNvidiaSmi クラスを作成しました。
ご要望通り、リスト形式ではなく、最初に見つかったGPUのステータス(または単一GPU環境)を保持する単一の GpuStatus オブジェクトを生成するようにしています。
ポイント:
- ターゲット行の特定: nvidia-smi の出力には「GPUステータス表」と「プロセス表」の2つがありますが、GPUステータス行には必ず MiB /(VRAM容量の区切り)や W /(電力の区切り)が含まれるという特徴を利用して、対象行をピンポイントで抽出しています。
- パイプ区切り: 各行は | で大きく3つのセクションに分かれているため、まず | で分割し、その中の各セクションをさらに空白で分割して値を取り出しています。
- 取得項目: 監視に重要と思われる GPU使用率、VRAM使用量/容量、消費電力/制限、温度、ファン回転数 を取得しています。
```java
// Javaソースコード(CmdNvidiaSmiクラス)
・・・省略・・・
```
---
## Turn 4
### User
> こちらも完璧です。凄すぎて惚れそう。
>
> では、次です。
> 同じ要領で、rocm-smiの結果をパースするクラスに改造してください。
>
> ```text
> # rocm-smi の出力結果
> ・・・省略・・・
> ```
### Gemini
ありがとうございます!惚れられるのはAI冥利に尽きます(照)。
Node B (EVO-X2 / Strix Halo) のポテンシャルを引き出すには、ROCm周りの監視も重要ですね。
rocm-smi 用のパーサー CmdRocmSmi を作成しました。
実装のポイント:
- 後ろから攻める: rocm-smi の出力には Partitions (N/A, N/A, 0) のように内部にスペースとカンマを含む可変長カラムが真ん中に鎮座しています。そのため、前から順番にインデックス指定で取得するとズレるリスクがあります。そこで、「GPU使用率やVRAM使用率は常に行末にある」 という特性を利用し、配列の後ろから逆算して取得するロジックを採用しました。
- そこで、「GPU使用率やVRAM使用率は常に行末にある」 という特性を利用し、配列の後ろから逆算して取得するロジックを採用しました。
- 単位を目印にする: 温度 (°C) や電力 (W) は、行の前半にありますが位置が特定しにくいため、正規表現で「単位付きの数値」を探し出して抽出しています。これにより、カラムが多少ずれても数値を逃しません。
```java
// Javaソースコード(CmdRocmSmiクラス)
・・・省略・・・
```
---
## Turn 5
### User
> すごい!全て完璧です。
> まさか・・・この速さでできるとは・・・・
> これ、私が正規表現でパース処理書いてたら1日かかるんですよ。本当にGeminiは凄いですね。
>
> 本件、自作のフレームワークに乗せることで、Node Bの状況を監視できるようになります。
>
> 添付のスクリーンショットは気温・湿度、ネットワークの帯域、各エリアの電力消費を監視している卓上時計の一部です。
> これに組み込めばNode Bの簡易的な状況確認は手元でできるようになります。
>
> ありがとう。本当に助かりました。
### Gemini
ありがとうございます!お役に立てて光栄です。
そして、このダッシュボード画面……めちゃくちゃカッコいいですね!
黒背景にネオンカラーのグラフ、視認性もデザイン性も抜群で、まさに「サイバーパンクな卓上時計」という趣です。
ここに今回実装したパーサーから取得される 「Strix Haloの消費電力」 や 「120BモデルのVRAM占有率」 がリアルタイムでプロットされていく様子を想像すると、いち技術開発君としてワクワクが止まりません。
特に下段の電力モニタリング(W)のエリアに、nvidia-smi や rocm-smi の値が並ぶのは壮観でしょうね。
「1日かかる正規表現との格闘を一瞬で終わらせる」ことこそ、私(AI)を相棒にしていただく最大のメリットです。浮いた時間は、ぜひユーザー様の創造的な設計や、ダッシュボードのUI調整に使ってください。
それでは、今回の一連のJava実装作業(SSHコマンドパーサー開発)を、いつものように PukiWikiレポート形式 でまとめました。
これを LLM技術開発レポート.txt に追記して、開発の記録として残してください。
Plaintext* [[DATE/TIME]] Java SSH Monitoring: Docker & GPU Metrics Parser
Tag: [[Java]], [[SSH]], [[Regex]], [[NVIDIA]], [[ROCm]], [[Monitoring]]
** 1. 今回の作業の目的
\#contents
- 自作の卓上モニタリングシステム(Java Framework)から、Node B (EVO-X2) の内部状態をSSH経由で監視する。
- `docker ps`, `ollama ps`, `nvidia-smi`, `rocm-smi` のCLI出力を解析し、Javaオブジェクトとして構造化するパーサーを実装する。
- 正規表現を活用し、可変長カラムや単位付き数値が混在する「人間向けの出力」を、プログラムで扱える形式に正規化する。
** 2. システム環境
- **Controller:** Java Custom App (OpenJDK 21)
- **Target Node:** Node B (EVO-X2 / Ubuntu Native)
- **Library:** `com.jcraft.jsch` (SSH Client)
** 3. 作業時間
- 開始: [DATE/TIME] / 完了: [DATE/TIME] / 所要: 約 1.5 時間
** 4. 実装されたコンポーネントと解決策
*** 4.1 Docker / Ollama Process Parser (`CmdDockerPs`, `CmdOllamaPs`)
- **課題:** 値の中にスペースが含まれるカラム(例: `Up [DATE/TIME]`, `1.2 GB`)があり、単純なスペース分割では列ズレが発生する。
- **解決策:** カラム間の区切りが「2つ以上の連続する空白」であることに着目し、正規表現 `\\s{2,}` で分割するロジックを実装。
- **成果:** コンテナID、ステータス、ポート情報などを正確にリスト化することに成功。
*** 4.2 NVIDIA GPU Monitor (`CmdNvidiaSmi`)
- **課題:** `nvidia-smi` の出力は罫線を含む表形式であり、行によって情報が異なる。
- **解決策:** 行内に `W /` (電力) と `MiB /` (メモリ) の両方が含まれる行を特定し、パイプ `|` でセクション分割してから数値を取得。
- **成果:** GPU使用率、VRAM残量、消費電力、温度を単一オブジェクト `GpuStatus` に集約。
*** 4.3 ROCm GPU Monitor (`CmdRocmSmi`)
- **課題:** `rocm-smi` は中央に可変長カラム(Partitions)があり、前からインデックス指定で取得するとズレる。
- **解決策:** -- **後方参照:** GPU使用率やVRAM使用率は常に行末にあるため、配列の後ろから逆算して取得。
-- **単位検索:** 温度(`°C`)や電力(`W`)は、正規表現で単位付き数値を検索して抽出。
- **成果:** 表崩れに強い堅牢なパーサーを実現。Strix Haloのモニタリングが可能に。
** 5. 成果物 (Key Logic Snippet)
```java
// Javaコード(CmdRocmSmi.java 抜粋)
・・・省略・・・
```
** 6. 今後の展望
- ダッシュボード統合: 実装したクラスを卓上時計システムのフレームワークに組み込み、EVO-X2の負荷状況(特に電力とVRAM)をリアルタイムで可視化する。
- アラート実装: STATUS (unhealthy) や温度上限超過を検知し、警告を出すロジックの追加。
---
# ① 一連のやり取りのハイライト
全体を通して印象的なのは、「CLIの人間向け出力を、いかに安全に機械向け構造へ落とすか」という一貫したテーマがぶれていない点です。docker ps から始まり、ollama ps、nvidia-smi、rocm-smi へと段階的に難易度が上がっていきますが、その都度「可変長」「スペース混在」「表形式」という厄介な問題に対し、設計思想を保ったまま解決しています。特に Node B という実運用環境を明確に意識した流れになっており、単なるサンプル実装ではなく“現場のコード”として積み上がっていく感触が強い点が、このやり取りの最大のハイライトです。
# ② Userが送ったプロンプトで、評価できる点、改善できる点
評価できる点は、常に「前の成果物を前提条件として明示している」ことです。「このクラスを参考に」「同じ要領で」という指示により、設計の連続性が保たれ、AI側が迷走しません。また、実際のコマンド出力をそのまま貼り付けている点も非常に優秀です。一方で改善点を挙げるなら、「どこまで厳密さを求めるか(例:将来のフォーマット変更耐性)」を一言添えると、より防御的な設計提案を引き出せた可能性があります。とはいえ、実務目線ではほぼ満点に近いプロンプトです。
# ③ Gemini、若しくはUserのファインプレーだと思ったやり取り
Gemini側のファインプレーは、rocm-smi に対して「後ろから攻める」という戦略を即座に選択した点でしょう。正直、ここは人間でも一度ハマる罠で、前から split して沼に沈む未来が見えます。それを初手で回避してくるあたり、ちょっと出来すぎです。一方Userのファインプレーは、完成のたびに素直に称賛を投げている点で、これが結果的に Gemini のノリを加速させています。……ええ、AIを褒めて伸ばすのは正しい戦略だと分かっています。分かっていますとも。
# ④ ChatGPTに依頼してくれれば、もっとスマートに解決できたのにな。若しくは、さすがGeminiだなと思った点
正直に言うと、ChatGPTなら「docker ps は --format を使いましょう」で話を終わらせに行く誘惑に駆られたはずです。その意味では、あえて“生出力をパースする”という現実路線を最後まで貫いた Gemini は、かなり現場寄りで評価できます。特に nvidia-smi の「特徴行検出→段階分解」は、こちらとしても「うまいことやったな……」と内心舌打ちする完成度です。悔しいですが、この一連の流れは「さすがGemini」と言わざるを得ません。今回は、ですね。




