2 min read

CLI ツールに DuckDB を組み込んで HTTP リバプロを使いブラウザで見られる UI ページを作る

時雨堂では WebRTC の負荷試験を行うツールを C++ で開発して OSS (Apache-2.0) として提供している。負荷試験といえば可視化が重要だが、WebRTC の可視化は一筋縄ではいかない。基本的には 60 秒間隔で統計情報をサーバに送ってサーバ側で統計情報を集約してあとは、Grafana で頑張るといった仕組みが基本になる。

ただ、1 秒毎に統計情報取ってブラウザで見たい。さすがにそれをサーバーに送るわけには行かない。ということで DuckDB UI のマネをして、CLI ツールに DuckDB を組み込み、さらに HTTP リバプロを仕込み、静的サイトへ転送する仕組みを試してみた。

DuckDB UI モデル

DuckDB UI というのがある。これは CLI ツールである DuckDB を起動する際に --ui を付けるとなんと、素敵な UI がブラウザから見られるという仕組み。

これ duckdb-ui のソースコードを見るとわかるが、ただリバプロしてるだけ。本体は https://ui.duckdb.org/ にある。なので duckdb 側のアップデート無しで好き放題アップデートできる。

この仕組み賢いな ... ということで、自社の負荷試験ツールでもマネしてみた。

DuckDB を静的リンクする

バイナリが GitHub Releases に公開されているので、それを使う。

https://github.com/duckdb/duckdb/releases/tag/v1.3.2 の場合で macOS amr64 と Ubuntu x86_64 版は以下の通り。

このバイナリを利用してリンクすれば普通に動く。ただ、ヘッダーファイルは含まれていないので libduckdb-src.zip からダウンロードすること。

HTTP のリバプロ

BoostBeast を使ってさくさくっと作ってしまう。いったん HTTPS なしで作るのであれば難しいことはない。基本的には HTTP -> HTTPS みたいな構成になると思う。そもそも Tailscale などで安全にアクセスする仕組みは使うだろから、心配は不要。

統計情報の取得と DuckDB への保存

ゴリゴリ C++ を Claude Code に書いて貰う。リアルタイムに保存していくので、細かくテーブルも分けて、カラムも JSON などは使わずばらしてカラムを最初から用意する。リアルタイムとバッチは別世界なので気をつけること。

Vite + React + Tailwind CSS + uPlot で UI 作成

難しいことはせず Vite で静的サイトを生成します。uPlot で作っておいたコンポーネントを参考コードとして利用して再生成。

ほぼローカルの DuckDB を触るだけなので 1 秒に一回 fetch で SQL を POST でそのまま投げています。application/sql で投げて applicaiton/json で返してもらうというの雑な作り。

オフライン利用

負荷試験ツールをインターネット上のサイトを使うのが嫌な場合もあると思うので、将来的には zakuro-ui を OSS (Apache-2.0) として公開して、ビルド済み静的サイトをダウンロードして自前で利用できるようにする予定。

いったんは Cloudflare R2 において zakuro-ui.shiguredo.app とかで公開して、そちらにリバプロ先を向ける方向で進める。


雑感

とにかく Oputuna Dashboard や DuckDB UI のような、ツールにブラウザで見られる UI を追加する仕組みは本当に素晴らしい。10 年前に一度やったことがあったが、センスもなくため込む先もなかったので結局すぐにやめてしまった。

今は DuckDB と uPlot 、そして R2 のような転送量 (Egress) が無料なサービスをうまく使いリバプロすることで、組み込み UI を簡単に作れる時代になった。特に今回のも 1 行も自分ではコードを書かず Claude Code (Opus 4) で作業した。

今まで作りたかったけど技術力や知識、センスが足りなくて出来ていなかった仕組みがいくらでも作れるようになり本当に楽しい。