Skip to content

Commit

Permalink
feat :: 컨테이너 로그 확인 API 개발
Browse files Browse the repository at this point in the history
  • Loading branch information
HyunSu1768 committed May 6, 2024
1 parent 935755d commit dee92fc
Show file tree
Hide file tree
Showing 10 changed files with 167 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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(
Expand Down Expand Up @@ -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)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package xquare.app.xquareinfra.domain.container.adapter.dto.response

data class GetContainerLogResponse(
val logs: List<Any?>
)
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -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])
}
}
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -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"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package xquare.app.xquareinfra.infrastructure.feign.client.log.dto

data class GetLogRequest(
val queries: List<QueryDto>,
val from: String,
val to: String
)
Original file line number Diff line number Diff line change
@@ -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<Frame>,
)

data class Frame(
val data: Data,
)

data class Data(
val values: List<List<Any?>>,
)
Original file line number Diff line number Diff line change
@@ -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
)

1 change: 1 addition & 0 deletions src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ server:

url:
deploy: ${DEPLOY_URL}
log: ${LOG_URL}

secret:
projectSecret: ${PROJECT_SECRET}
Expand Down

0 comments on commit dee92fc

Please sign in to comment.