[feature] add some api, etc..

- add some api
- add /metrics routing
This commit is contained in:
dalbodeule
2025-07-15 21:52:41 +09:00
parent 9e3a79a613
commit 66df771cb7
8 changed files with 143 additions and 4 deletions

View File

@@ -11,6 +11,7 @@ import io.ktor.serialization.kotlinx.json.*
import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.engine.*
import io.ktor.server.metrics.micrometer.MicrometerMetrics
import io.ktor.server.netty.*
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.server.plugins.cors.routing.*
@@ -19,9 +20,16 @@ import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.server.sessions.*
import io.ktor.server.websocket.*
import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics
import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics
import io.micrometer.core.instrument.binder.system.ProcessorMetrics
import io.micrometer.prometheusmetrics.PrometheusConfig
import io.micrometer.prometheusmetrics.PrometheusMeterRegistry
import kotlinx.coroutines.delay
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import org.koin.core.context.startKoin
import org.koin.dsl.module
import org.koin.java.KoinJavaComponent.inject
import space.mori.chzzk_bot.common.events.CoroutinesEventBus
import space.mori.chzzk_bot.common.events.UserRegisterEvent
@@ -232,6 +240,18 @@ val server = embeddedServer(Netty, port = 8080, ) {
}
}
val appMicrometerRegistry: PrometheusMeterRegistry by inject(PrometheusMeterRegistry::class.java)
install(MicrometerMetrics) {
registry = appMicrometerRegistry
meterBinders = listOf(
JvmMemoryMetrics(),
JvmGcMetrics(),
ProcessorMetrics()
)
}
apiRoutes()
apiSongRoutes()
apiCommandRoutes()
@@ -242,6 +262,8 @@ val server = embeddedServer(Netty, port = 8080, ) {
wsSongRoutes()
wsSongListRoutes()
metricRoutes()
swaggerUI("swagger-ui/index.html", "openapi/documentation.yaml") {
options {
version = "1.2.0"

View File

@@ -1,6 +1,7 @@
package space.mori.chzzk_bot.webserver.routes
import io.ktor.http.*
import io.ktor.server.request.receive
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.server.sessions.*
@@ -15,6 +16,7 @@ import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.withTimeoutOrNull
import space.mori.chzzk_bot.common.events.ChzzkUserFindEvent
import space.mori.chzzk_bot.common.events.ChzzkUserReceiveEvent
import space.mori.chzzk_bot.webserver.routes.GuildSettings
@Serializable
data class GetUserDTO(
@@ -146,4 +148,48 @@ fun Routing.apiRoutes() {
call.respond(HttpStatusCode.OK, returnUsers)
}
}
}
route("/settings") {
get {
val session = call.sessions.get<UserSession>()
if(session == null) {
call.respondText("No session found", status = HttpStatusCode.Unauthorized)
return@get
}
val user = UserService.getUser(session.id)
if(user == null) {
call.respondText("No user found", status = HttpStatusCode.NotFound)
return@get
}
call.respond(HttpStatusCode.OK, IUserSettingsDTO(
user.isDisabled,
user.isDisableStartupMsg
))
}
post {
val session = call.sessions.get<UserSession>()
val body: IUserSettingsDTO = call.receive()
if(session == null) {
call.respondText("No session found", status = HttpStatusCode.Unauthorized)
return@post
}
val user = UserService.getUser(session.id)
if(user == null) {
call.respondText("No user found", status = HttpStatusCode.NotFound)
return@post
}
UserService.setIsDisabled(user, body.isBotDisabled)
UserService.setIsStartupDisabled(user, body.isBotMsgDisabled)
call.respond(HttpStatusCode.OK, body)
}
}
}
data class IUserSettingsDTO(
val isBotDisabled: Boolean,
val isBotMsgDisabled: Boolean
)

View File

@@ -0,0 +1,36 @@
package space.mori.chzzk_bot.webserver.routes
import io.ktor.server.application.ApplicationStopped
import io.ktor.server.response.respondText
import io.ktor.server.routing.Routing
import io.ktor.server.routing.get
import io.micrometer.prometheusmetrics.PrometheusMeterRegistry
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import org.koin.java.KoinJavaComponent.inject
import space.mori.chzzk_bot.common.events.CoroutinesEventBus
import space.mori.chzzk_bot.common.events.UserRegisterEvent
import space.mori.chzzk_bot.common.metrics.Metrics
import kotlin.getValue
val metricScope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
fun Routing.metricRoutes() {
environment.monitor.subscribe(ApplicationStopped) {
metricScope.cancel()
}
val dispatcher: CoroutinesEventBus by inject(CoroutinesEventBus::class.java)
val registry: PrometheusMeterRegistry by inject(PrometheusMeterRegistry::class.java)
dispatcher.subscribe(UserRegisterEvent::class) {
Metrics.streamer++
}
get("/metrics") {
call.respondText(registry.scrape())
}
}