読み上げ文字数の集計#38
Merged
MORIMORI0317 merged 7 commits intoMay 20, 2026
Merged
Conversation
Bot/サーバー単位 + 日次で読み上げ文字数とメッセージ数をDBに集計記録する。 SQLite/MySQL双方でアトミックUPSERTにより同時書き込みでもロストしない。 - 新規テーブル tts_count_data (bot_id, server_id, target_date 単位) - TTSCountRecorder で読み上げ確定時に非同期記録 - Micrometer Prometheus レジストリで /metrics エンドポイント公開 (デフォルト 127.0.0.1:9095, 設定で無効化可) - /stat コマンド (today/week/all/server) で Bot 所有者向けに集計表示 - 起動時に DB 累計値を Counter に注入し再起動後も整合
- server_id = 0 をBot全体合計の予約値とし、server_id IS NULLの分岐を削除
unique制約とON CONFLICT/ON DUPLICATE KEY UPDATE単一クエリに統一しrace conditionを解消
- /stat week でメッセージ数も表示
- TTSCountData#getRecord を追加し、StatCommand での2重SELECTを解消
- 起動時のCounter累計注入を削除 (Prometheusのrate計算を狂わせるため)
- MetricsRegistry の getOrCreate{Char,Message}Counter を共通化
- DataRepositoryImpl の sum 系ボイラープレートをwithConnectionヘルパで集約
- botId解決を getBot().getBotId() に統一
- RELATIVE_TIME_FORMAT を BaseCommand に集約
- PrometheusHttpExposer に固定スレッドプールを設定し詰まりを回避
- MetricsRegistryをinterface化しPrometheus実装とNoOp実装を分離 メトリクス無効時もnon-nullになり呼び出し側のnullチェックを削除 - ITTSRuntimeUseにgetTTSCountRecorder/getMetricsRegistryのdefaultを追加 VoiceAudioSchedulerのITTSRuntime.getInstance()プルを既存パターンに統一 - ITTSRuntime#initMetricsを生成と起動に限定し、シャットダウンフック登録を registerShutdownHooksに分離
集計機能のマージ後に別PRで対応する方針のため、 Prometheus関連の実装を本PRから取り除く - core/metrics配下を削除 - MetricsConfigを削除 - ITTSRuntime/Use・Config・selfhost ConfigImplから参照を除去 - Micrometer依存を削除 - TTSCountRecorderはDB書き込みのみに簡略化
- core.statistics パッケージを新設し、TTSCount 関連を集約 - statistics.enable / statistics.data_base コンフィグを追加 - 保存先を save_data.db から statistics_data.db (または独立MySQLスキーマ) に分離 - 集計粒度にボイス別 (voice_type / voice_category) を追加 - 本体 DAO/Repository から TTSCount 関連を全削除
32eb81a to
ce4f0f9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Discord議論 (MG / MORIMORI0317) で出ていた「Bot稼働状況・読み上げ量」要件のうち、集計部分の実装
/statコマンド (today/week/all/server)カウント単位は 辞書適用 + read_limitカット後に音声合成APIへ渡した最終テキストの
String.length()(UTF-16)。外部API課金との相関が高く、計測コストもゼロ。厳密モーラ数は別途検討余地あり。レビュー反映 (追加対応)
MORIMORI0317 さんのレビュー (Discord, ER図 + config 案) を踏まえて以下を実装:
statistics.enable/statistics.data_baseを新設 (本体DBコンフィグと同構造)save_data.dbからstatistics_data.db(または独立MySQLスキーマ) に分離。本体DAOからtts_count_dataを完全削除dev.felnull.itts.core.statisticsを新設して関連コードを全て集約tts_count_dataにvoice_type_id/voice_category_idFK を追加、voice_type_key/voice_category_keyテーブル新設未リリース機能のため破壊的変更で対応。本体DB側のスキーマには一切変更なし。
新パッケージ構成
コンフィグ例
主な追加・変更ファイル
core.statistics.*配下一式 (DAO / Repository / Manager / Recorder / Config)Config#getStatisticsConfig()追加 +selfhost/ConfigImplに JSON5 マッピング追加VoiceAudioScheduler—recorder.record(..., voice, ...)に変更StatCommand—StatisticsManager経由に切替、無効時は「統計機能は無効になっています」を返すDAO/SQLiteDAO/MySQLDAO/DataRepository(Impl)から TTSCount 関連を全削除TTSCountStatisticsTestを新パッケージに移動 + ボイス対応検証
./gradlew clean build(checkstyle 含めて成功)./gradlew :core:test --tests "*.statistics.*"(8並列スレッド × 50回 incrementCount でロスト無し、ボイス別集計確認)./gradlew :selfhost:shadowJarTest plan
statistics.enable: true+sqliteで起動 →statistics_data.dbが生成されるtts_count_dataに bot/server/voice/date/count が記録されるbot_key/server_key/voice_type_key/voice_category_keyが正しく FK 解決されているsave_data.db側にtts_count_dataが 存在しない こと/stat today/stat week/stat all/stat server表示確認statistics.enable: falseで再起動 → 統計DBが生成されず/statが無効化メッセージを返すtype: "mysql"(ITTS_STATISTICSスキーマ) で再度上記確認留意点
String.length()。要件で言及された「ひらがな1文字=1モーラ」厳密値ではない近似feat/tts-prometheusに実装済み)save_data.dbにtts_count_dataがある場合は手動で対処が必要 (未リリース機能のため許容)