Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ dependencies {
api("org.xerial:sqlite-jdbc:3.51.1.0")
api("it.unimi.dsi:fastutil:8.5.18")

api("io.micrometer:micrometer-core:1.13.6")
api("io.micrometer:micrometer-registry-prometheus:1.13.6")

api("org.jetbrains:annotations:26.0.2-1")

// api("org.apache.logging.log4j:log4j-core:3.0.0-beta3")
Expand Down
84 changes: 84 additions & 0 deletions core/src/main/java/dev/felnull/itts/core/ITTSRuntime.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@
import dev.felnull.itts.core.audio.VoiceAudioManager;
import dev.felnull.itts.core.cache.CacheManager;
import dev.felnull.itts.core.config.ConfigManager;
import dev.felnull.itts.core.config.MetricsConfig;
import dev.felnull.itts.core.dict.DictionaryManager;
import dev.felnull.itts.core.discord.Bot;
import dev.felnull.itts.core.metrics.MetricsRegistry;
import dev.felnull.itts.core.metrics.PrometheusHttpExposer;
import dev.felnull.itts.core.metrics.PrometheusMetricsRegistry;
import dev.felnull.itts.core.savedata.SaveDataManager;
import dev.felnull.itts.core.tts.TTSCountRecorder;
import dev.felnull.itts.core.tts.TTSManager;
import dev.felnull.itts.core.voice.VoiceManager;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
Expand Down Expand Up @@ -129,6 +134,22 @@ public class ITTSRuntime {
*/
private long startupTime;

/**
* メトリクスレジストリ
* 公開無効時はNoOp実装が入る
*/
private MetricsRegistry metricsRegistry;

/**
* Prometheusメトリクス公開HTTPサーバー
*/
private PrometheusHttpExposer prometheusHttpExposer;

/**
* 読み上げ文字数のレコーダー
*/
private TTSCountRecorder ttsCountRecorder;

private ITTSRuntime(ITTSRuntimeContext runtimeContext) {
if (instance != null) {
throw new IllegalStateException("ITTSRuntime must be a singleton instance");
Expand Down Expand Up @@ -202,9 +223,53 @@ public void execute() {

logger.info("Setup complete");

initMetrics();
registerShutdownHooks();

bot.start();
}

/**
* メトリクス関連コンポーネントを生成し起動する
* 公開無効時はNoOp実装を採用しnullを返さない
*/
private void initMetrics() {
MetricsConfig metricsConfig = configManager.getConfig().getMetricsConfig();

if (!metricsConfig.isEnabled()) {
this.metricsRegistry = MetricsRegistry.noop();
this.ttsCountRecorder = new TTSCountRecorder(metricsRegistry);
logger.info("Prometheus metrics is disabled");
return;
}

PrometheusMetricsRegistry prometheusRegistry = new PrometheusMetricsRegistry();
this.metricsRegistry = prometheusRegistry;
this.ttsCountRecorder = new TTSCountRecorder(metricsRegistry);

try {
this.prometheusHttpExposer = new PrometheusHttpExposer(prometheusRegistry);
this.prometheusHttpExposer.start(metricsConfig.getBindAddress(), metricsConfig.getPort());
logger.info("Prometheus metrics endpoint started on {}:{}/metrics", metricsConfig.getBindAddress(), metricsConfig.getPort());
} catch (Exception e) {
logger.warn("Failed to start Prometheus HTTP exposer", e);
this.prometheusHttpExposer = null;
}
}

/**
* シャットダウンフックを登録する
* メトリクスHTTPサーバなどライフサイクル管理対象を集約する
*/
private void registerShutdownHooks() {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
PrometheusHttpExposer exposer = this.prometheusHttpExposer;
if (exposer != null) {
exposer.stop();
}
}, "prometheus-exposer-shutdown"));
}

public long getStartupTime() {
return startupTime;
}
Expand Down Expand Up @@ -273,4 +338,23 @@ public ITTSNetworkManager getNetworkManager() {
public Bot getBot() {
return bot;
}

/**
* 読み上げ文字数のレコーダーを取得
*
* @return レコーダー
*/
public TTSCountRecorder getTTSCountRecorder() {
return ttsCountRecorder;
}

/**
* メトリクスレジストリを取得
* 公開無効時はNoOp実装が返るためnullにはならない
*
* @return メトリクスレジストリ
*/
public MetricsRegistry getMetricsRegistry() {
return metricsRegistry;
}
}
21 changes: 21 additions & 0 deletions core/src/main/java/dev/felnull/itts/core/ITTSRuntimeUse.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import dev.felnull.itts.core.config.ConfigManager;
import dev.felnull.itts.core.dict.DictionaryManager;
import dev.felnull.itts.core.discord.Bot;
import dev.felnull.itts.core.metrics.MetricsRegistry;
import dev.felnull.itts.core.tts.TTSCountRecorder;
import dev.felnull.itts.core.tts.TTSManager;
import dev.felnull.itts.core.voice.VoiceManager;
import org.apache.logging.log4j.Logger;
Expand Down Expand Up @@ -83,4 +85,23 @@ default Bot getBot() {
default ITTSNetworkManager getNetworkManager() {
return getITTSRuntime().getNetworkManager();
}

/**
* 読み上げ文字数のレコーダーを取得
*
* @return TTSカウントレコーダー
*/
default TTSCountRecorder getTTSCountRecorder() {
return getITTSRuntime().getTTSCountRecorder();
}

/**
* メトリクスレジストリを取得
* 公開無効時もNoOp実装が返るためnullにはならない
*
* @return メトリクスレジストリ
*/
default MetricsRegistry getMetricsRegistry() {
return getITTSRuntime().getMetricsRegistry();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason;
import dev.felnull.itts.core.ITTSRuntimeUse;
import dev.felnull.itts.core.audio.loader.VoiceTrackLoader;
import dev.felnull.itts.core.tts.TTSCountRecorder;
import dev.felnull.itts.core.tts.saidtext.SaidText;
import dev.felnull.itts.core.util.TTSUtils;
import dev.felnull.itts.core.voice.Voice;
Expand Down Expand Up @@ -94,7 +95,15 @@ public CompletableFuture<LoadedSaidText> load(SaidText saidText) {

Objects.requireNonNull(voice, "Voice is null");

return Pair.of(TTSUtils.roundText(voice, guildId, sayText, false), voice);
String finalText = TTSUtils.roundText(voice, guildId, sayText, false);

TTSCountRecorder recorder = getTTSCountRecorder();
if (recorder != null && finalText != null) {
long botId = getBot().getBotId();
recorder.record(botId, guildId, finalText.length());
}

return Pair.of(finalText, voice);
}, getAsyncExecutor())
.thenComposeAsync((sayTextVoice) -> {
VoiceTrackLoader vtl = sayTextVoice.getRight().createVoiceTrackLoader(sayTextVoice.getLeft());
Expand Down
9 changes: 9 additions & 0 deletions core/src/main/java/dev/felnull/itts/core/config/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,13 @@ public interface Config {
* @return DB関係のコンフィグ
*/
DataBaseConfig getDataBaseConfig();

/**
* Prometheusメトリクスのコンフィグを取得
*
* @return メトリクスコンフィグ
*/
default MetricsConfig getMetricsConfig() {
return MetricsConfig.DEFAULT;
}
}
66 changes: 66 additions & 0 deletions core/src/main/java/dev/felnull/itts/core/config/MetricsConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package dev.felnull.itts.core.config;

import org.jetbrains.annotations.NotNull;

/**
* Prometheusメトリクス公開のコンフィグ
*/
public interface MetricsConfig {

/**
* デフォルトの有効状態
*/
boolean DEFAULT_ENABLED = false;

/**
* デフォルトのバインドアドレス
*/
String DEFAULT_BIND_ADDRESS = "127.0.0.1";

/**
* デフォルトのポート番号
*/
int DEFAULT_PORT = 9095;

/**
* デフォルトのコンフィグインスタンス
*/
MetricsConfig DEFAULT = new MetricsConfig() {
@Override
public boolean isEnabled() {
return DEFAULT_ENABLED;
}

@Override
public @NotNull String getBindAddress() {
return DEFAULT_BIND_ADDRESS;
}

@Override
public int getPort() {
return DEFAULT_PORT;
}
};

/**
* 有効かどうかを取得
*
* @return 有効かどうか
*/
boolean isEnabled();

/**
* バインドアドレスを取得
*
* @return バインドアドレス
*/
@NotNull
String getBindAddress();

/**
* ポート番号を取得
*
* @return ポート番号
*/
int getPort();
}
1 change: 1 addition & 0 deletions core/src/main/java/dev/felnull/itts/core/discord/Bot.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ private void registeringCommands() {
registerCommand(new AdminCommand());
registerCommand(new DictCommand());
registerCommand(new SkipCommand());
registerCommand(new StatCommand());
}

private void registerCommand(BaseCommand command) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ public abstract class BaseCommand implements ITTSRuntimeUse {
*/
protected static final DefaultMemberPermissions OWNERS_PERMISSIONS = DefaultMemberPermissions.enabledFor(Permission.MANAGE_SERVER);

/**
* 時間を相対的に表示するフォーマット
*/
protected static final String RELATIVE_TIME_FORMAT = "<t:%d:R>";

/**
* コマンド名
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ public class InfoCommand extends BaseCommand {
*/
private static final String SOURCE_URL = "https://github.com/TeamFelnull/I-TTS";

/**
* 時間を相対的に表示するフォーマット
*/
private static final String RELATIVE_TIME_FORMAT = "<t:%d:R>";

/**
* コンストラクタ
*/
Expand Down
Loading
Loading