From e96cb14e645eb5c370840d72abb6c3e094477e7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A8=B8=ED=99=98=EC=9E=84?= <88091704+daehwan2da@users.noreply.github.com> Date: Sat, 2 Mar 2024 21:04:41 +0900 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8:=20apply=20global=20KLogger=20#18=20(?= =?UTF-8?q?#19)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 2 ++ .../th/plu/api/service/auth/jwt/JwtHandler.kt | 17 ++++++------ .../com/th/plu/common/Slf4JKotlinLogging.kt | 9 +++++++ .../aop/advice/ExceptionControllerAdvice.kt | 26 +++++++++---------- .../firebase/WebClientFirebaseApiCaller.kt | 24 ++++++++++------- .../plu/external/sqs/sender/SqsSenderImpl.kt | 5 ++-- .../firebase/FirebaseCloudMessageService.kt | 7 +++-- .../th/plu/notification/sqs/SqsConsumer.kt | 19 +++++++++----- 8 files changed, 63 insertions(+), 46 deletions(-) create mode 100644 plu-common/src/main/kotlin/com/th/plu/common/Slf4JKotlinLogging.kt diff --git a/build.gradle.kts b/build.gradle.kts index 3402080..dcbdb7d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -44,8 +44,10 @@ subprojects { compileOnly("org.projectlombok:lombok") annotationProcessor("org.projectlombok:lombok") + // kotlin implementation("com.fasterxml.jackson.module:jackson-module-kotlin") implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation("io.github.oshai:kotlin-logging-jvm:5.1.0") testImplementation("org.springframework.boot:spring-boot-starter-test") } diff --git a/plu-api/src/main/kotlin/com/th/plu/api/service/auth/jwt/JwtHandler.kt b/plu-api/src/main/kotlin/com/th/plu/api/service/auth/jwt/JwtHandler.kt index 3c5a2b8..d49e861 100644 --- a/plu-api/src/main/kotlin/com/th/plu/api/service/auth/jwt/JwtHandler.kt +++ b/plu-api/src/main/kotlin/com/th/plu/api/service/auth/jwt/JwtHandler.kt @@ -1,6 +1,7 @@ package com.th.plu.api.service.auth.jwt import com.th.plu.api.service.redis.RedisHandler +import com.th.plu.common.Slf4JKotlinLogging.log import com.th.plu.common.constant.JwtKey import com.th.plu.common.constant.RedisKey import com.th.plu.common.exception.code.ErrorCode @@ -10,7 +11,6 @@ import io.jsonwebtoken.io.Decoders import io.jsonwebtoken.io.DecodingException import io.jsonwebtoken.security.Keys import jakarta.annotation.PostConstruct -import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Value import org.springframework.stereotype.Component import java.security.Key @@ -23,7 +23,6 @@ class JwtHandler( @Value("\${jwt.secret}") private var jwtSecret: String? = null private var secretKey: Key? = null - private val log = LoggerFactory.getLogger(this.javaClass) companion object { // private const val ACCESS_TOKEN_EXPIRE_TIME = 10 * 60 * 1000L // 10분 @@ -71,19 +70,19 @@ class JwtHandler( Jwts.parserBuilder().setSigningKey(secretKey).build().parseClaimsJws(token) return true } catch (e: SecurityException) { - log.warn("Invalid JWT Token", e) + log.warn(e) { "Invalid JWT Token" } } catch (e: MalformedJwtException) { - log.warn("Invalid JWT Token", e) + log.warn(e) { "Invalid JWT Token" } } catch (e: DecodingException) { - log.warn("Invalid JWT Token", e) + log.warn(e) { "Invalid JWT Token" } } catch (e: ExpiredJwtException) { - log.warn("Expired JWT Token", e) + log.warn(e) { "Expired JWT Token" } } catch (e: UnsupportedJwtException) { - log.warn("Unsupported JWT Token", e) + log.warn(e) { "Unsupported JWT Token" } } catch (e: IllegalArgumentException) { - log.warn("JWT claims string is empty.", e) + log.warn(e) { "JWT claims string is empty." } } catch (e: Exception) { - log.error("Unhandled JWT exception", e) + log.error(e) { "Unhandled JWT exception" } } return false } diff --git a/plu-common/src/main/kotlin/com/th/plu/common/Slf4JKotlinLogging.kt b/plu-common/src/main/kotlin/com/th/plu/common/Slf4JKotlinLogging.kt new file mode 100644 index 0000000..386c6be --- /dev/null +++ b/plu-common/src/main/kotlin/com/th/plu/common/Slf4JKotlinLogging.kt @@ -0,0 +1,9 @@ +package com.th.plu.common + +import io.github.oshai.kotlinlogging.KLogger +import io.github.oshai.kotlinlogging.KotlinLogging + +object Slf4JKotlinLogging { + val T.log: KLogger + inline get() = KotlinLogging.logger {} +} \ No newline at end of file diff --git a/plu-common/src/main/kotlin/com/th/plu/common/aop/advice/ExceptionControllerAdvice.kt b/plu-common/src/main/kotlin/com/th/plu/common/aop/advice/ExceptionControllerAdvice.kt index 9746400..27c1695 100644 --- a/plu-common/src/main/kotlin/com/th/plu/common/aop/advice/ExceptionControllerAdvice.kt +++ b/plu-common/src/main/kotlin/com/th/plu/common/aop/advice/ExceptionControllerAdvice.kt @@ -1,10 +1,10 @@ package com.th.plu.common.aop.advice import com.fasterxml.jackson.databind.exc.InvalidFormatException +import com.th.plu.common.Slf4JKotlinLogging.log import com.th.plu.common.dto.response.ApiResponse import com.th.plu.common.exception.code.ErrorCode import com.th.plu.common.exception.model.* -import org.slf4j.LoggerFactory import org.springframework.http.HttpStatus import org.springframework.http.converter.HttpMessageNotReadableException import org.springframework.validation.BindException @@ -20,22 +20,20 @@ import org.springframework.web.servlet.resource.NoResourceFoundException @RestControllerAdvice class ExceptionControllerAdvice { - private val log = LoggerFactory.getLogger(this.javaClass) - /** * 400 Bad Request */ @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(ValidationException::class) fun handleValidationException(exception: ValidationException): ApiResponse { - log.error(exception.message) + log.error(exception) { exception.message } return ApiResponse.error(exception.errorCode) } @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(MethodArgumentNotValidException::class) fun handleMethodArgumentNotValidException(exception: MethodArgumentNotValidException): ApiResponse { - log.error(exception.message, exception); + log.error(exception) { exception.message } return ApiResponse.error( ErrorCode.METHOD_ARGUMENT_NOT_VALID_EXCEPTION, exception.bindingResult.fieldError?.defaultMessage.toString() @@ -45,7 +43,7 @@ class ExceptionControllerAdvice { @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(BindException::class) fun handleBindException(exception: BindException): ApiResponse { - log.error(exception.message, exception); + log.error(exception) { exception.message } return ApiResponse.error( ErrorCode.BIND_EXCEPTION, exception.bindingResult.fieldError?.defaultMessage.toString() @@ -61,7 +59,7 @@ class ExceptionControllerAdvice { ] ) fun handleInvalidFormatException(exception: Exception): ApiResponse { - log.error(exception.message, exception); + log.error(exception) { exception.message } return ApiResponse.error(ErrorCode.INVALID_FORMAT_EXCEPTION); } @@ -71,7 +69,7 @@ class ExceptionControllerAdvice { @ResponseStatus(HttpStatus.UNAUTHORIZED) @ExceptionHandler(UnauthorizedException::class) fun handleUnauthorizedException(exception: UnauthorizedException): ApiResponse { - log.error(exception.message, exception) + log.error(exception) { exception.message } return ApiResponse.error(exception.errorCode) } @@ -81,7 +79,7 @@ class ExceptionControllerAdvice { @ResponseStatus(HttpStatus.FORBIDDEN) @ExceptionHandler(ForbiddenException::class) fun handleForbiddenException(exception: ForbiddenException): ApiResponse { - log.error(exception.message, exception) + log.error(exception) { exception.message } return ApiResponse.error(exception.errorCode) } @@ -91,7 +89,7 @@ class ExceptionControllerAdvice { @ResponseStatus(HttpStatus.NOT_FOUND) @ExceptionHandler(NotFoundException::class) fun handleNotFoundException(exception: NotFoundException): ApiResponse { - log.error(exception.message, exception) + log.error(exception) { exception.message } return ApiResponse.error(exception.errorCode) } @@ -102,7 +100,7 @@ class ExceptionControllerAdvice { NoResourceFoundException::class] ) fun handleNotFoundEndpointException(exception: Exception): ApiResponse { - log.error(exception.message, exception) + log.error(exception) { exception.message } return ApiResponse.error(ErrorCode.NOT_FOUND_ENDPOINT_EXCEPTION) } @@ -121,7 +119,7 @@ class ExceptionControllerAdvice { @ResponseStatus(HttpStatus.CONFLICT) @ExceptionHandler(ConflictException::class) fun handleConflictException(exception: ConflictException): ApiResponse { - log.error(exception.message, exception) + log.error(exception) { exception.message } return ApiResponse.error(exception.errorCode) } @@ -140,7 +138,7 @@ class ExceptionControllerAdvice { @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ExceptionHandler(Exception::class) fun handleInternalServerException(exception: Exception): ApiResponse { - log.error(exception.message, exception) + log.error(exception) { exception.message } return ApiResponse.error(ErrorCode.INTERNAL_SERVER_EXCEPTION) } @@ -150,7 +148,7 @@ class ExceptionControllerAdvice { @ResponseStatus(HttpStatus.BAD_GATEWAY) @ExceptionHandler(BadGatewayException::class) fun handleBadGatewayException(exception: BadGatewayException): ApiResponse { - log.error(exception.message, exception) + log.error(exception) { exception.message } return ApiResponse.error(exception.errorCode) } } diff --git a/plu-external/src/main/kotlin/com/th/plu/external/client/firebase/WebClientFirebaseApiCaller.kt b/plu-external/src/main/kotlin/com/th/plu/external/client/firebase/WebClientFirebaseApiCaller.kt index 359d12a..4652bd9 100644 --- a/plu-external/src/main/kotlin/com/th/plu/external/client/firebase/WebClientFirebaseApiCaller.kt +++ b/plu-external/src/main/kotlin/com/th/plu/external/client/firebase/WebClientFirebaseApiCaller.kt @@ -1,9 +1,8 @@ package com.th.plu.external.client.firebase +import com.th.plu.common.Slf4JKotlinLogging.log import com.th.plu.common.exception.code.ErrorCode import com.th.plu.common.exception.model.BadGatewayException -import com.th.plu.common.exception.model.ValidationException -import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Value import org.springframework.http.HttpStatusCode import org.springframework.http.MediaType @@ -19,7 +18,6 @@ class WebClientFirebaseApiCaller(private val webClient: WebClient) : FirebaseApi @Value("\${spring.cloud.firebase.message.uri}") private var messageApiUri: String? = null - private val log = LoggerFactory.getLogger(this.javaClass) private val LOG_PREFIX = "====> [Firebase Messaging]" @@ -33,19 +31,25 @@ class WebClientFirebaseApiCaller(private val webClient: WebClient) : FirebaseApi .body(BodyInserters.fromValue(message)) .retrieve() .onStatus(HttpStatusCode::is4xxClientError) { - Mono.error(BadGatewayException(ErrorCode.BAD_GATEWAY_EXCEPTION, - createFirebaseFailMessage(it, message) - )) + Mono.error( + BadGatewayException( + ErrorCode.BAD_GATEWAY_EXCEPTION, + createFirebaseFailMessage(it, message) + ) + ) } .onStatus(HttpStatusCode::is5xxServerError) { - Mono.error(BadGatewayException(ErrorCode.BAD_GATEWAY_EXCEPTION, - createFirebaseFailMessage(it, message) - )) + Mono.error( + BadGatewayException( + ErrorCode.BAD_GATEWAY_EXCEPTION, + createFirebaseFailMessage(it, message) + ) + ) } .toBodilessEntity() .subscribe { if (it.statusCode.is2xxSuccessful) { - log.info("${LOG_PREFIX}\nStatus: ${it.statusCode}\nMessage: ${message}") + log.info { "${LOG_PREFIX}\nStatus: ${it.statusCode}\nMessage: ${message}" } } else { throw BadGatewayException( ErrorCode.BAD_GATEWAY_EXCEPTION, diff --git a/plu-external/src/main/kotlin/com/th/plu/external/sqs/sender/SqsSenderImpl.kt b/plu-external/src/main/kotlin/com/th/plu/external/sqs/sender/SqsSenderImpl.kt index ddf8b06..1ae425d 100644 --- a/plu-external/src/main/kotlin/com/th/plu/external/sqs/sender/SqsSenderImpl.kt +++ b/plu-external/src/main/kotlin/com/th/plu/external/sqs/sender/SqsSenderImpl.kt @@ -1,10 +1,10 @@ package com.th.plu.external.sqs.sender import com.fasterxml.jackson.databind.ObjectMapper +import com.th.plu.common.Slf4JKotlinLogging.log import com.th.plu.external.sqs.dto.FirebaseMessageDto import io.awspring.cloud.sqs.operations.SendResult import io.awspring.cloud.sqs.operations.SqsTemplate -import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Value import org.springframework.stereotype.Component import java.util.* @@ -15,13 +15,12 @@ class SqsSenderImpl(private val objectMapper: ObjectMapper, private val sqsTempl @Value("\${spring.cloud.aws.sqs.queue.name}") private var queueName: String? = null - private val log = LoggerFactory.getLogger(this.javaClass) private val LOG_PREFIX = "====> [SQS_SENDER]" private val GROUP_ID = "plu-sqs" private val MESSAGE_TYPE_HEADER = "type" override fun sendFirebaseMessage(message: FirebaseMessageDto): SendResult { - log.info("${LOG_PREFIX} send Message(type: ${message.type})") + log.info { "$LOG_PREFIX send Message(type: ${message.type})" } return sqsTemplate.send { it.queue(queueName.toString()) it.header(MESSAGE_TYPE_HEADER, message.type.name) diff --git a/plu-notification/src/main/kotlin/com/th/plu/notification/firebase/FirebaseCloudMessageService.kt b/plu-notification/src/main/kotlin/com/th/plu/notification/firebase/FirebaseCloudMessageService.kt index 34e35c8..21b827e 100644 --- a/plu-notification/src/main/kotlin/com/th/plu/notification/firebase/FirebaseCloudMessageService.kt +++ b/plu-notification/src/main/kotlin/com/th/plu/notification/firebase/FirebaseCloudMessageService.kt @@ -2,11 +2,11 @@ package com.th.plu.notification.firebase import com.fasterxml.jackson.databind.ObjectMapper import com.google.auth.oauth2.GoogleCredentials +import com.th.plu.common.Slf4JKotlinLogging.log import com.th.plu.common.exception.code.ErrorCode import com.th.plu.common.exception.model.BadGatewayException import com.th.plu.external.client.firebase.FirebaseApiCaller import com.th.plu.notification.firebase.dto.FcmMessageRequest -import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Value import org.springframework.core.io.ClassPathResource import org.springframework.stereotype.Service @@ -22,7 +22,6 @@ class FirebaseCloudMessageService( @Value("\${spring.cloud.firebase.auth.uri}") private var firebaseAuthUri: String? = null - private val log = LoggerFactory.getLogger(this.javaClass) private val LOG_PREFIX = "====> [Firebase Cloud Message]" fun sendMessageTo(fcmToken: String?, title: String, body: String) { @@ -46,10 +45,10 @@ class FirebaseCloudMessageService( return googleCredentials.accessToken.tokenValue } catch (exception: Exception) { - log.error(exception.message, exception) + log.error(exception) { exception.message } throw BadGatewayException( ErrorCode.BAD_GATEWAY_EXCEPTION, - "${LOG_PREFIX} FCM Access Token 발급 과정에서 에러가 발생하였습니다." + "$LOG_PREFIX FCM Access Token 발급 과정에서 에러가 발생하였습니다." ) } } diff --git a/plu-notification/src/main/kotlin/com/th/plu/notification/sqs/SqsConsumer.kt b/plu-notification/src/main/kotlin/com/th/plu/notification/sqs/SqsConsumer.kt index e186b93..9b61cb4 100644 --- a/plu-notification/src/main/kotlin/com/th/plu/notification/sqs/SqsConsumer.kt +++ b/plu-notification/src/main/kotlin/com/th/plu/notification/sqs/SqsConsumer.kt @@ -1,13 +1,13 @@ package com.th.plu.notification.sqs import com.fasterxml.jackson.databind.ObjectMapper +import com.th.plu.common.Slf4JKotlinLogging.log import com.th.plu.common.exception.code.ErrorCode import com.th.plu.common.exception.model.InternalServerException import com.th.plu.external.sqs.dto.FirebaseMessageDto import com.th.plu.external.sqs.dto.MessageType import com.th.plu.notification.firebase.FirebaseCloudMessageService import io.awspring.cloud.sqs.annotation.SqsListener -import org.slf4j.LoggerFactory import org.springframework.messaging.handler.annotation.Headers import org.springframework.messaging.handler.annotation.Payload import org.springframework.stereotype.Service @@ -17,7 +17,6 @@ class SqsConsumer( private val objectMapper: ObjectMapper, private val FirebaseCloudMessageService: FirebaseCloudMessageService ) { - private val log = LoggerFactory.getLogger(this.javaClass) private val LOG_PREFIX = "====> [SQS Queue Request]"; private val MESSAGE_TYPE_HEADER = "type" @@ -25,17 +24,25 @@ class SqsConsumer( @SqsListener("pluNotification.fifo") fun consume(@Payload info: String, @Headers headers: Map) { try { - log.info("${LOG_PREFIX}\ninfo: ${info}\nheaders: ${headers}") + log.info { "$LOG_PREFIX\ninfo: ${info}\nheaders: $headers" } val messageType = headers.get(MESSAGE_TYPE_HEADER) when (messageType) { MessageType.FIREBASE.name -> { val firebaseMessageDto = objectMapper.readValue(info, FirebaseMessageDto::class.java) - FirebaseCloudMessageService.sendMessageTo(firebaseMessageDto.fcmToken, firebaseMessageDto.title, firebaseMessageDto.body) + FirebaseCloudMessageService.sendMessageTo( + firebaseMessageDto.fcmToken, + firebaseMessageDto.title, + firebaseMessageDto.body + ) } + else -> - throw InternalServerException(ErrorCode.INTERNAL_SERVER_EXCEPTION, "${LOG_PREFIX} 존재하지 않는 MessageType(${headers.get(MESSAGE_TYPE_HEADER)} 입니다.") + throw InternalServerException( + ErrorCode.INTERNAL_SERVER_EXCEPTION, + "${LOG_PREFIX} 존재하지 않는 MessageType(${headers.get(MESSAGE_TYPE_HEADER)} 입니다." + ) } - } catch (exception : Exception) { + } catch (exception: Exception) { throw Exception(exception.message, exception) } }