From dee92fc6b46b49d52f1f8ab329c995353755ea9b Mon Sep 17 00:00:00 2001 From: HyunSu1768 Date: Mon, 6 May 2024 22:47:39 +0900 Subject: [PATCH] =?UTF-8?q?feat=20::=20=EC=BB=A8=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=84=88=20=EB=A1=9C=EA=B7=B8=20=ED=99=95=EC=9D=B8=20API=20?= =?UTF-8?q?=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../container/adapter/ContainerWebAdapter.kt | 15 +++++- .../dto/response/GetContainerLogResponse.kt | 5 ++ .../port/in/GetContainerLogUseCase.kt | 8 +++ .../service/GetContainerService.kt | 53 +++++++++++++++++++ .../feign/client/log/LogClient.kt | 18 +++++++ .../feign/client/log/LogUtil.kt | 29 ++++++++++ .../feign/client/log/dto/GetLogRequest.kt | 7 +++ .../feign/client/log/dto/LogResponse.kt | 24 +++++++++ .../feign/client/log/dto/QueryDto.kt | 8 +++ src/main/resources/application.yaml | 1 + 10 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/xquare/app/xquareinfra/domain/container/adapter/dto/response/GetContainerLogResponse.kt create mode 100644 src/main/kotlin/xquare/app/xquareinfra/domain/container/application/port/in/GetContainerLogUseCase.kt create mode 100644 src/main/kotlin/xquare/app/xquareinfra/domain/container/application/service/GetContainerService.kt create mode 100644 src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/log/LogClient.kt create mode 100644 src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/log/LogUtil.kt create mode 100644 src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/log/dto/GetLogRequest.kt create mode 100644 src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/log/dto/LogResponse.kt create mode 100644 src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/log/dto/QueryDto.kt diff --git a/src/main/kotlin/xquare/app/xquareinfra/domain/container/adapter/ContainerWebAdapter.kt b/src/main/kotlin/xquare/app/xquareinfra/domain/container/adapter/ContainerWebAdapter.kt index 45aa0b5..8fd5762 100644 --- a/src/main/kotlin/xquare/app/xquareinfra/domain/container/adapter/ContainerWebAdapter.kt +++ b/src/main/kotlin/xquare/app/xquareinfra/domain/container/adapter/ContainerWebAdapter.kt @@ -8,6 +8,8 @@ import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController import xquare.app.xquareinfra.domain.container.adapter.dto.request.SyncContainerRequest +import xquare.app.xquareinfra.domain.container.adapter.dto.response.GetContainerLogResponse +import xquare.app.xquareinfra.domain.container.application.port.`in`.GetContainerLogUseCase import xquare.app.xquareinfra.domain.container.application.port.`in`.GetEnvironmentVariableUseCase import xquare.app.xquareinfra.domain.container.application.port.`in`.SyncContainerUseCase import xquare.app.xquareinfra.domain.container.application.port.`in`.UpdateEnvironmentVariableUseCase @@ -18,7 +20,8 @@ import xquare.app.xquareinfra.domain.container.domain.ContainerEnvironment class ContainerWebAdapter( private val syncContainerUseCase: SyncContainerUseCase, private val getEnvironmentVariableUseCase: GetEnvironmentVariableUseCase, - private val updateEnvironmentVariableUseCase: UpdateEnvironmentVariableUseCase + private val updateEnvironmentVariableUseCase: UpdateEnvironmentVariableUseCase, + private val getContainerLogUseCase: GetContainerLogUseCase ) { @PostMapping("/sync") fun syncContainer( @@ -51,4 +54,14 @@ class ContainerWebAdapter( ) { updateEnvironmentVariableUseCase.updateEnvironmentVariable(deployName, environment, environmentVariable) } + + @GetMapping("/logs") + fun getContainerLog( + @RequestParam("deploy_name", required = true) + deployName: String, + @RequestParam("environment", required = true) + environment: ContainerEnvironment, + ): GetContainerLogResponse { + return getContainerLogUseCase.getContainerLog(deployName, environment) + } } \ No newline at end of file diff --git a/src/main/kotlin/xquare/app/xquareinfra/domain/container/adapter/dto/response/GetContainerLogResponse.kt b/src/main/kotlin/xquare/app/xquareinfra/domain/container/adapter/dto/response/GetContainerLogResponse.kt new file mode 100644 index 0000000..882de75 --- /dev/null +++ b/src/main/kotlin/xquare/app/xquareinfra/domain/container/adapter/dto/response/GetContainerLogResponse.kt @@ -0,0 +1,5 @@ +package xquare.app.xquareinfra.domain.container.adapter.dto.response + +data class GetContainerLogResponse( + val logs: List +) diff --git a/src/main/kotlin/xquare/app/xquareinfra/domain/container/application/port/in/GetContainerLogUseCase.kt b/src/main/kotlin/xquare/app/xquareinfra/domain/container/application/port/in/GetContainerLogUseCase.kt new file mode 100644 index 0000000..38991aa --- /dev/null +++ b/src/main/kotlin/xquare/app/xquareinfra/domain/container/application/port/in/GetContainerLogUseCase.kt @@ -0,0 +1,8 @@ +package xquare.app.xquareinfra.domain.container.application.port.`in` + +import xquare.app.xquareinfra.domain.container.adapter.dto.response.GetContainerLogResponse +import xquare.app.xquareinfra.domain.container.domain.ContainerEnvironment + +interface GetContainerLogUseCase { + fun getContainerLog(deployName: String, environment: ContainerEnvironment): GetContainerLogResponse +} \ No newline at end of file diff --git a/src/main/kotlin/xquare/app/xquareinfra/domain/container/application/service/GetContainerService.kt b/src/main/kotlin/xquare/app/xquareinfra/domain/container/application/service/GetContainerService.kt new file mode 100644 index 0000000..62fbea2 --- /dev/null +++ b/src/main/kotlin/xquare/app/xquareinfra/domain/container/application/service/GetContainerService.kt @@ -0,0 +1,53 @@ +package xquare.app.xquareinfra.domain.container.application.service + +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional +import xquare.app.xquareinfra.domain.container.adapter.dto.response.GetContainerLogResponse +import xquare.app.xquareinfra.domain.container.application.port.`in`.GetContainerLogUseCase +import xquare.app.xquareinfra.domain.container.application.port.out.FindContainerPort +import xquare.app.xquareinfra.domain.container.domain.ContainerEnvironment +import xquare.app.xquareinfra.domain.deploy.application.port.out.FindDeployPort +import xquare.app.xquareinfra.infrastructure.exception.BusinessLogicException +import xquare.app.xquareinfra.infrastructure.feign.client.log.LogClient +import xquare.app.xquareinfra.infrastructure.feign.client.log.LogUtil +import xquare.app.xquareinfra.infrastructure.feign.client.log.dto.GetLogRequest +import xquare.app.xquareinfra.infrastructure.feign.client.log.dto.QueryDto +import java.time.Instant + +@Transactional(readOnly = true) +@Service +class GetContainerService( + private val findContainerPort: FindContainerPort, + private val findDeployPort: FindDeployPort, + private val logClient: LogClient +): GetContainerLogUseCase { + override fun getContainerLog(deployName: String, environment: ContainerEnvironment): GetContainerLogResponse { + val deploy = findDeployPort.findByDeployName(deployName) ?: throw BusinessLogicException.DEPLOY_NOT_FOUND + val container = findContainerPort.findByDeployAndEnvironment(deploy, environment) + ?: throw BusinessLogicException.CONTAINER_NOT_FOUND + + val currentTimeMillis = Instant.now().toEpochMilli() + val twentyFourHoursAgoMillis = currentTimeMillis - (24 * 60 * 60 * 1000) + + val response = logClient.getLogs( + GetLogRequest( + queries = listOf( + QueryDto( + expr = LogUtil.makeLogQuery( + team = deploy.team.teamNameEn, + containerName = deployName, + serviceType = deploy.deployType, + envType = environment + ), + refId = "A", + datasource = "loki" + ) + ), + from = twentyFourHoursAgoMillis.toString(), + to = currentTimeMillis.toString() + ) + ) + + return GetContainerLogResponse(response.results.a.frames[0].data.values[2]) + } +} \ No newline at end of file diff --git a/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/log/LogClient.kt b/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/log/LogClient.kt new file mode 100644 index 0000000..3179b72 --- /dev/null +++ b/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/log/LogClient.kt @@ -0,0 +1,18 @@ +package xquare.app.xquareinfra.infrastructure.feign.client.log + +import org.springframework.cloud.openfeign.FeignClient +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestBody +import xquare.app.xquareinfra.infrastructure.feign.client.log.dto.GetLogRequest +import xquare.app.xquareinfra.infrastructure.feign.client.log.dto.LogResponse +import xquare.app.xquareinfra.infrastructure.feign.config.FeignConfig + +@FeignClient( + name = "tsdata-client", + url = "\${url.log}", + configuration = [FeignConfig::class] +) +interface LogClient { + @PostMapping("/api/ds/query") + fun getLogs(@RequestBody getLogRequest: GetLogRequest): LogResponse +} \ No newline at end of file diff --git a/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/log/LogUtil.kt b/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/log/LogUtil.kt new file mode 100644 index 0000000..082a025 --- /dev/null +++ b/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/log/LogUtil.kt @@ -0,0 +1,29 @@ +package xquare.app.xquareinfra.infrastructure.feign.client.log + +import xquare.app.xquareinfra.domain.container.domain.ContainerEnvironment +import xquare.app.xquareinfra.domain.deploy.domain.DeployType + +object LogUtil { + fun extractOrganization(githubUrl: String): String { + val parts = githubUrl.split("/") + return if (parts.size >= 4) { + parts[3] + } else { + "" + } + } + + fun getRepository(githubUrl: String): String { + val parts = githubUrl.split("/") + return if (parts.size >= 4) { + "${parts[3]}/${parts[4]}" + } else { + "" + } + } + + fun makeLogQuery(team: String, containerName: String, serviceType: DeployType, envType: ContainerEnvironment): String { + val fullName = "${containerName}-${serviceType.toString().lowercase()}-${envType.toString().lowercase()}" + return "{job=\"$team-${envType.toString().lowercase()}/$fullName\", container=~\"$fullName\", stream=~\"stdout\"} |~ \"(?i)\" \n" + } +} \ No newline at end of file diff --git a/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/log/dto/GetLogRequest.kt b/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/log/dto/GetLogRequest.kt new file mode 100644 index 0000000..14dc67c --- /dev/null +++ b/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/log/dto/GetLogRequest.kt @@ -0,0 +1,7 @@ +package xquare.app.xquareinfra.infrastructure.feign.client.log.dto + +data class GetLogRequest( + val queries: List, + val from: String, + val to: String +) \ No newline at end of file diff --git a/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/log/dto/LogResponse.kt b/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/log/dto/LogResponse.kt new file mode 100644 index 0000000..3d2bbce --- /dev/null +++ b/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/log/dto/LogResponse.kt @@ -0,0 +1,24 @@ +package xquare.app.xquareinfra.infrastructure.feign.client.log.dto + +import com.fasterxml.jackson.annotation.JsonProperty + +data class LogResponse( + val results: Results, +) + +data class Results( + @JsonProperty("A") + val a: A, +) + +data class A( + val frames: List, +) + +data class Frame( + val data: Data, +) + +data class Data( + val values: List>, +) diff --git a/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/log/dto/QueryDto.kt b/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/log/dto/QueryDto.kt new file mode 100644 index 0000000..781d9c7 --- /dev/null +++ b/src/main/kotlin/xquare/app/xquareinfra/infrastructure/feign/client/log/dto/QueryDto.kt @@ -0,0 +1,8 @@ +package xquare.app.xquareinfra.infrastructure.feign.client.log.dto + +data class QueryDto( + val expr: String, + val refId: String, + val datasource: String +) + diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 73b4f0b..a1a6a60 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -56,6 +56,7 @@ server: url: deploy: ${DEPLOY_URL} + log: ${LOG_URL} secret: projectSecret: ${PROJECT_SECRET}