watchdog-be: 各状態のオブジェクトの数を取得できるように

This commit is contained in:
usbharu 2024-03-13 16:00:54 +09:00
parent ce7ac9eb4b
commit ea80da90d2
Signed by: usbharu
GPG Key ID: 6556747BF94EEBC8
3 changed files with 43 additions and 9 deletions

View File

@ -29,6 +29,9 @@ fun Route.api(apiController: ApiController){
get("/not-good"){ get("/not-good"){
call.respond(HttpStatusCode.OK,apiController.getNotGood()) call.respond(HttpStatusCode.OK,apiController.getNotGood())
} }
get {
call.respond(HttpStatusCode.OK,apiController.statusCount())
}
} }
} }
} }
@ -53,4 +56,8 @@ class ApiController(private val metricsRepository: MetricsRepository) {
fun getNotGood():Flow<Metric>{ fun getNotGood():Flow<Metric>{
return metricsRepository.findByStatusAndGroupByObjectIdMaxTimestamp(Status.NOT_GOOD) return metricsRepository.findByStatusAndGroupByObjectIdMaxTimestamp(Status.NOT_GOOD)
} }
suspend fun statusCount():Map<Status,Int>{
return metricsRepository.countyGroupByObjectIdMaxTimestamp()
}
} }

View File

@ -7,4 +7,6 @@ interface MetricsRepository {
suspend fun save(metric: Metric):Metric suspend fun save(metric: Metric):Metric
fun findByObjectId(objectId:String): Flow<Metric> fun findByObjectId(objectId:String): Flow<Metric>
fun findByStatusAndGroupByObjectIdMaxTimestamp(status: Status): Flow<Metric> fun findByStatusAndGroupByObjectIdMaxTimestamp(status: Status): Flow<Metric>
suspend fun countyGroupByObjectIdMaxTimestamp():Map<Status,Int>
} }

View File

@ -9,7 +9,9 @@ import com.mongodb.kotlin.client.coroutine.MongoDatabase
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlinx.serialization.Serializable
class MongoMetricsRepository(database: MongoDatabase) : MetricsRepository { class MongoMetricsRepository(database: MongoDatabase) : MetricsRepository {
@ -27,15 +29,15 @@ class MongoMetricsRepository(database: MongoDatabase) : MetricsRepository {
return collection.aggregate( return collection.aggregate(
listOf( listOf(
Aggregates.group( Aggregates.group(
"$"+Metric::objectId.name, "$" + Metric::objectId.name,
Accumulators.max(Metric::timestamp.name, "$" + Metric::timestamp.name), Accumulators.max(Metric::timestamp.name, "$" + Metric::timestamp.name),
Accumulators.first(Metric::id.name, "\$_id"), Accumulators.last(Metric::id.name, "\$_id"),
Accumulators.first(Metric::objectId.name, "$" + Metric::objectId.name), Accumulators.last(Metric::objectId.name, "$" + Metric::objectId.name),
Accumulators.first(Metric::domain.name, "$" + Metric::domain.name), Accumulators.last(Metric::domain.name, "$" + Metric::domain.name),
Accumulators.first(Metric::status.name, "$" + Metric::status.name), Accumulators.last(Metric::status.name, "$" + Metric::status.name),
Accumulators.first(Metric::value.name, "$" + Metric::value.name), Accumulators.last(Metric::value.name, "$" + Metric::value.name),
Accumulators.first(Metric::name.name, "$" + Metric::name.name), Accumulators.last(Metric::name.name, "$" + Metric::name.name),
Accumulators.first(Metric::message.name,"$"+ Metric::message.name) Accumulators.last(Metric::message.name, "$" + Metric::message.name)
), ),
Aggregates.project( Aggregates.project(
Projections.fields( Projections.fields(
@ -48,11 +50,34 @@ class MongoMetricsRepository(database: MongoDatabase) : MetricsRepository {
Metric::name.name, Metric::name.name,
Metric::message.name Metric::message.name
), ),
Projections.computed("_id","$"+ Metric::id.name) Projections.computed("_id", "$" + Metric::id.name)
) )
), ),
Aggregates.match(Filters.eq(Metric::status.name, status)) Aggregates.match(Filters.eq(Metric::status.name, status))
) )
).flowOn(Dispatchers.IO) ).flowOn(Dispatchers.IO)
} }
override suspend fun countyGroupByObjectIdMaxTimestamp(): Map<Status, Int> {
return collection.aggregate<StatusIntMap>(
listOf(
Aggregates.group(
"$" + Metric::objectId.name,
Accumulators.max(Metric::timestamp.name, "$" + Metric::timestamp.name),
Accumulators.last(Metric::status.name, "$" + Metric::status.name),
),
Aggregates.group(
"\$status",
Accumulators.first("status","\$status"),
Accumulators.sum("count", 1)
)
)
).flowOn(Dispatchers.IO).toList().associate { it.status to it.count }
}
@Serializable
data class StatusIntMap(
val status: Status,
val count: Int
)
} }