Skip to content

Commit

Permalink
7/10 배포 작업 (#126)
Browse files Browse the repository at this point in the history
  • Loading branch information
cookienc authored Jul 10, 2024
1 parent 6451fc1 commit b6ef483
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 4 deletions.
10 changes: 10 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ dependencies {
// solapi
implementation 'net.nurigo:sdk:4.2.7'

// loggin
implementation 'org.springframework.boot:spring-boot-starter-log4j2'

runtimeOnly 'com.h2database:h2'
runtimeOnly 'com.mysql:mysql-connector-j'

Expand Down Expand Up @@ -98,3 +101,10 @@ tasks.register('copySecret', Copy) {
tasks.named('compileJava') {
inputs.files(tasks.named('processResources'))
}

// logging
configurations {
all {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class GlobalRestControllerAdvice : ResponseEntityExceptionHandler() {

@ExceptionHandler(FirstLoginException::class, DuplicatedMemberException::class)
fun handleFirstLoginException(e: ClientException): ResponseEntity<ErrorResponse> {
logger.info("message : ", e)
logger.error("message : ", e)

return ResponseEntity.status(e.errorCode.httpStatus)
.body(ErrorResponse.from(e.errorCode))
Expand All @@ -26,7 +26,7 @@ class GlobalRestControllerAdvice : ResponseEntityExceptionHandler() {
fun handleBeanInstantiationException(e: BeanInstantiationException): ResponseEntity<String> {
return when (val ex = e.cause) {
is IllegalArgumentException -> {
logger.info("사용자 입력 예외입니다. message : ", ex)
logger.error("사용자 입력 예외입니다. message : ", ex)
ResponseEntity.badRequest().body("사용자 입력 예외입니다.")
}

Expand All @@ -39,14 +39,14 @@ class GlobalRestControllerAdvice : ResponseEntityExceptionHandler() {

@ExceptionHandler(IllegalArgumentException::class)
fun handleIllealArgumentException(e: IllegalArgumentException): ResponseEntity<String> {
logger.info("사용자 입력 예외입니다. message : ", e)
logger.error("사용자 입력 예외입니다. message : ", e)

return ResponseEntity.badRequest().body("사용자 입력 예외입니다.")
}

@ExceptionHandler(OauthRequestException::class)
fun handleIllealArgumentException(e: OauthRequestException): ResponseEntity<String> {
logger.info("잘못된 로그인 방식입니다. message : ", e)
logger.error("잘못된 로그인 방식입니다. message : ", e)

return ResponseEntity.badRequest().body("잘못된 로그인 방식입니다.")
}
Expand Down
85 changes: 85 additions & 0 deletions src/main/kotlin/backend/itracker/logging/aspect/LoggerAspect.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package backend.itracker.logging.aspect

import com.google.common.net.HttpHeaders
import io.github.oshai.kotlinlogging.KotlinLogging
import jakarta.servlet.http.HttpServletRequest
import org.aspectj.lang.JoinPoint
import org.aspectj.lang.annotation.AfterReturning
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Before
import org.aspectj.lang.annotation.Pointcut
import org.slf4j.MDC
import org.springframework.context.annotation.Profile
import org.springframework.stereotype.Component
import org.springframework.web.context.request.RequestContextHolder
import org.springframework.web.context.request.ServletRequestAttributes
import java.util.*


private val LOGGER = KotlinLogging.logger {}
private val IP_HEADERS = listOf(
HttpHeaders.X_FORWARDED_FOR,
"Proxy-Client-IP",
"WL-Proxy-Client-IP",
"HTTP_CLIENT_IP",
"HTTP_X_FORWARDED_FOR"
)

@Profile("!test")
@Component
@Aspect
class LoggerAspect {

@Pointcut(
""" @annotation(org.springframework.web.bind.annotation.PostMapping) ||
@annotation(org.springframework.web.bind.annotation.GetMapping) ||
@annotation(org.springframework.web.bind.annotation.PatchMapping) ||
@annotation(org.springframework.web.bind.annotation.PutMapping) ||
@annotation(org.springframework.web.bind.annotation.DeleteMapping)"""
)
fun apiInfo() {
}

@Before("apiInfo()")
fun beforeApiRequest(joinPoint: JoinPoint) {
val request =
(Objects.requireNonNull(RequestContextHolder.getRequestAttributes()) as ServletRequestAttributes).request
LOGGER.info {
"""
[ API Start ]
- Request ID: ${getRequestId()}
- Method: ${request.method}
- URI: ${getURI(request)}
- IP: ${getClientIP(request)}
- Signature: ${getSignature(joinPoint)}
""".trimIndent()
}
}

@AfterReturning(value = "apiInfo()", returning = "response")
fun afterApiRequest(response: Any) {
LOGGER.info {
"""
[ API End ]
- Request ID: ${getRequestId()}
- Response: $response
""".trimIndent()
}
}

private fun getRequestId(): String {
return MDC.get("request_id")
}

private fun getURI(request: HttpServletRequest): String {
return "${request.requestURI}${request.queryString.let { if (it != null) "?$it" else "" }}"
}

private fun getClientIP(request: HttpServletRequest): String? {
return IP_HEADERS.firstNotNullOfOrNull { header -> request.getHeader(header) } ?: request.remoteAddr
}

private fun getSignature(joinPoint: JoinPoint): String {
return "${joinPoint.signature.declaringType.simpleName}.${joinPoint.signature.name}"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package backend.itracker.logging.filter

import jakarta.servlet.Filter
import jakarta.servlet.FilterChain
import jakarta.servlet.ServletRequest
import jakarta.servlet.ServletResponse
import jakarta.servlet.http.HttpServletRequest
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?, chain: FilterChain?) {
val requestId = (request as HttpServletRequest).getHeader("X-Request-ID")
MDC.put("request_id", requestId ?: UUID.randomUUID().toString())

chain!!.doFilter(request, response)

MDC.clear()
}
}
1 change: 1 addition & 0 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ spring:
highlight_sql: true

logging:
config: classpath:logger/log4j2.xml
level:
org.hibernate.SQL: debug
org.hibernate.orm.jdbc.bind: TRACE
Expand Down
39 changes: 39 additions & 0 deletions src/main/resources/logger/log4j2.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Properties>
<Property name="FILE_NAME">daily-log</Property>
<Property name="WARN_FILE_NAME">warn-log</Property>
<Property name="ERROR_FILE_NAME">error-log</Property>
<Property name="BASE_DIR">logs</Property>
<Property name="COLOR_PATTERN">%style{%d{ISO8601}}{white} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable</Property>
<Property name="PATTERN">[%equals{%X{request_id}}{}{startup}] %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Property>
</Properties>

<Appenders>
<Console name="console" target="SYSTEM_OUT" follow="true">
<PatternLayout pattern="${COLOR_PATTERN}" charset="UTF-8"/>
</Console>

<RollingFile name="dailyFile">
<FileName>${BASE_DIR}/${FILE_NAME}.log</FileName>
<FilePattern>${BASE_DIR}/${FILE_NAME}-%d{yyyy-MM-dd}.%i.log.gz</FilePattern>
<PatternLayout pattern="${PATTERN}" />
<Policies>
<SizeBasedTriggeringPolicy size="50MB"/>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
<DefaultRolloverStrategy max="7" fileIndex="max">
<Delete basePath="${BASE_DIR}" maxDepth="1">
<IfLastModified age = "15d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>

<Loggers>
<Root level="INFO" additivity="false">
<AppenderRef ref="console"/>
<AppenderRef ref="dailyFile"/>
</Root>
</Loggers>
</Configuration>

0 comments on commit b6ef483

Please sign in to comment.