diff --git a/docker/dev/docker-compose.yml b/docker/dev/docker-compose.yml index 04bd24e3..e8a90219 100644 --- a/docker/dev/docker-compose.yml +++ b/docker/dev/docker-compose.yml @@ -11,6 +11,8 @@ services: - TZ=Asia/Seoul networks: - server-network + volumes: + - /home/ubuntu/logs:/app/logs redis: image: redis:latest ports: diff --git a/docker/prod/docker-compose.yml b/docker/prod/docker-compose.yml index 7f06af2e..b475d3f8 100644 --- a/docker/prod/docker-compose.yml +++ b/docker/prod/docker-compose.yml @@ -1,10 +1,12 @@ services: backend: - image: yugyeong390/photi-server:1.1.1 + image: yugyeong390/photi-server:1.1.2 env_file: - .env ports: - "8080:8080" + volumes: + - /home/ubuntu/logs:/app/logs environment: - TZ=Asia/Seoul networks: diff --git a/src/main/kotlin/com/photi/server/common/log/LoggingTaskDecorator.kt b/src/main/kotlin/com/photi/server/common/log/LoggingTaskDecorator.kt new file mode 100644 index 00000000..884a75f0 --- /dev/null +++ b/src/main/kotlin/com/photi/server/common/log/LoggingTaskDecorator.kt @@ -0,0 +1,18 @@ +package com.photi.server.common.log + +import org.slf4j.MDC +import org.springframework.core.task.TaskDecorator + +class LoggingTaskDecorator : TaskDecorator { + + override fun decorate(task: Runnable): Runnable { + val callerThreadContext = MDC.getCopyOfContextMap() + + return Runnable { + callerThreadContext?.let { + MDC.setContextMap(it) + } + task.run() + } + } +} diff --git a/src/main/kotlin/com/photi/server/common/log/MDCLoggingFilter.kt b/src/main/kotlin/com/photi/server/common/log/MDCLoggingFilter.kt new file mode 100644 index 00000000..842fcf82 --- /dev/null +++ b/src/main/kotlin/com/photi/server/common/log/MDCLoggingFilter.kt @@ -0,0 +1,31 @@ +package com.photi.server.common.log + +import jakarta.servlet.Filter +import jakarta.servlet.FilterChain +import jakarta.servlet.ServletRequest +import jakarta.servlet.ServletResponse +import org.slf4j.MDC +import org.springframework.core.Ordered +import org.springframework.core.annotation.Order +import org.springframework.stereotype.Component +import java.util.* + +@Component +@Order(Ordered.HIGHEST_PRECEDENCE) +class MDCLoggingFilter : Filter { + + override fun doFilter( + request: ServletRequest, + response: ServletResponse, + filterChain: FilterChain, + ) { + val uuid = UUID.randomUUID() + MDC.put(REQUEST_ID, uuid.toString()) + filterChain.doFilter(request, response) + MDC.clear() + } + + companion object { + const val REQUEST_ID = "request_id" + } +} diff --git a/src/main/kotlin/com/photi/server/config/AsyncConfig.kt b/src/main/kotlin/com/photi/server/config/AsyncConfig.kt index 91fd3add..557541f9 100644 --- a/src/main/kotlin/com/photi/server/config/AsyncConfig.kt +++ b/src/main/kotlin/com/photi/server/config/AsyncConfig.kt @@ -1,24 +1,31 @@ package com.photi.server.config import com.photi.server.common.exception.CustomAsyncUncaughtExceptionHandler +import com.photi.server.common.log.LoggingTaskDecorator import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler import org.springframework.context.annotation.Configuration import org.springframework.scheduling.annotation.AsyncConfigurer import org.springframework.scheduling.annotation.EnableAsync import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor -import java.util.concurrent.Executor +import java.util.concurrent.ThreadPoolExecutor @EnableAsync @Configuration class AsyncConfig : AsyncConfigurer { - override fun getAsyncExecutor(): Executor? { + override fun getAsyncExecutor(): ThreadPoolTaskExecutor { return ThreadPoolTaskExecutor().apply { - corePoolSize = 3 - maxPoolSize = 10 - queueCapacity = 500 + corePoolSize = 10 + queueCapacity = 50 + maxPoolSize = 30 + keepAliveSeconds = 60 setThreadNamePrefix("Executor-") - initialize() + setTaskDecorator(LoggingTaskDecorator()) + setRejectedExecutionHandler(ThreadPoolExecutor.CallerRunsPolicy()) + setWaitForTasksToCompleteOnShutdown(true) + setAwaitTerminationSeconds(20) + setAcceptTasksAfterContextClose(false) + setAllowCoreThreadTimeOut(false) } } diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml new file mode 100644 index 00000000..a1f7f519 --- /dev/null +++ b/src/main/resources/logback-spring.xml @@ -0,0 +1,47 @@ + + + + + + + + + + ${LOG_PATTERN} + + + + + + ${LOG_PATTERN} + + + ${LOG_PATH}/%d{yyyy-MM-dd}.%i.log + 1 + 200MB + 10MB + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/logback/dev-logback.xml b/src/main/resources/logback/dev-logback.xml deleted file mode 100644 index dc079df9..00000000 --- a/src/main/resources/logback/dev-logback.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - %clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){green} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx} - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/logback/prod-logback.xml b/src/main/resources/logback/prod-logback.xml deleted file mode 100644 index 295e90e6..00000000 --- a/src/main/resources/logback/prod-logback.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - %clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){green} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx} - - - - - - ${ROLLING_LOG_FILEPATH}/${ROLLING_LOG_FILENAME}.log - - UTF-8 - - %clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){green} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx} - - - - ${ROLLING_LOG_FILEPATH}/${ROLLING_LOG_FILENAME}_%d{yyyy-MM-dd}_%i.log - - 50MB - - - - - - - error - ACCEPT - DENY - - ${ERROR_LOG_FILEPATH}/${ERROR_LOG_FILENAME}.log - - UTF-8 - - %clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){green} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx} - - - - ${ERROR_LOG_FILEPATH}/${ERROR_LOG_FILENAME}_%d{yyyy-MM-dd}_%i.log - - 100MB - - - - - - - - - - \ No newline at end of file