Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature/BE] 로깅 구현 #351

Merged
merged 1 commit into from
Aug 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ sourceCompatibility = '11'

configurations {
asciidoctorExtensions
all {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
}

repositories {
Expand All @@ -22,6 +25,8 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.boot:spring-boot-starter-log4j2'
implementation 'com.lmax:disruptor:3.4.2'

runtimeOnly 'com.h2database:h2'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,51 +25,59 @@ public class GlobalExceptionHandler {

private static final String REQUEST_DATA_FORMAT_ERROR_MESSAGE = "요청으로 넘어온 값이 형식에 맞지 않습니다.";
private static final String INTERNAL_SERVER_ERROR_MESSAGE = "서버 오류가 발생했습니다";
private static final String LOG_FORMAT = "Class : {}, Code : {}, Message : {}";

@ExceptionHandler(NotFoundException.class)
public ResponseEntity<ExceptionResponse> handleNotFoundException(final NotFoundException e) {
log.info(LOG_FORMAT, e.getClass().getSimpleName(), e.getErrorCode().getValue(), e.getMessage());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ExceptionResponse.from(e));
}

@ExceptionHandler(InvalidValueException.class)
public ResponseEntity<ExceptionResponse> handleInvalidValueException(final InvalidValueException e) {
log.info(LOG_FORMAT, e.getClass().getSimpleName(), e.getErrorCode().getValue(), e.getMessage());
return ResponseEntity.badRequest().body(ExceptionResponse.from(e));
}

@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<ExceptionResponse> handleHttpMessageNotReadableException() {
public ResponseEntity<ExceptionResponse> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
log.info(LOG_FORMAT, e.getClass().getSimpleName(), INVALID_REQUEST_BODY.getValue(), e.getMessage());
return ResponseEntity.badRequest()
.body(ExceptionResponse.from(REQUEST_DATA_FORMAT_ERROR_MESSAGE, INVALID_REQUEST_BODY));
}

@ExceptionHandler({BindException.class, MethodArgumentTypeMismatchException.class})
public ResponseEntity<ExceptionResponse> handleInvalidQueryParameterException() {
public ResponseEntity<ExceptionResponse> handleInvalidQueryParameterException(Exception e) {
log.info(LOG_FORMAT, e.getClass().getSimpleName(), INVALID_SEARCH_PARAM.getValue(), e.getMessage());
return ResponseEntity.badRequest()
.body(ExceptionResponse.from(REQUEST_DATA_FORMAT_ERROR_MESSAGE, INVALID_SEARCH_PARAM));
}

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ExceptionResponse> handleValidationException(
final MethodArgumentNotValidException exception) {
final MethodArgumentNotValidException e) {
log.info(LOG_FORMAT, e.getClass().getSimpleName(), INVALID_REQUEST_BODY.getValue(), e.getMessage());
final StringBuilder stringBuilder = new StringBuilder();
exception.getBindingResult().getAllErrors().forEach((error) -> stringBuilder.append(error.getDefaultMessage())
e.getBindingResult().getAllErrors().forEach((error) -> stringBuilder.append(error.getDefaultMessage())
.append(System.lineSeparator()));
return ResponseEntity.badRequest().body(ExceptionResponse.from(stringBuilder.toString(), INVALID_REQUEST_BODY));
}

@ExceptionHandler(UnauthorizedException.class)
public ResponseEntity<ExceptionResponse> handleUnauthorizedException(final UnauthorizedException e) {
log.info(LOG_FORMAT, e.getClass().getSimpleName(), e.getErrorCode().getValue(), e.getMessage());
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(ExceptionResponse.from(e));
}

@ExceptionHandler(ForbiddenMemberException.class)
public ResponseEntity<ExceptionResponse> handleForbiddenMemberException(final ForbiddenMemberException e) {
log.info(LOG_FORMAT, e.getClass().getSimpleName(), e.getErrorCode().getValue(), e.getMessage());
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(ExceptionResponse.from(e));
}

@ExceptionHandler(Exception.class)
public ResponseEntity<ExceptionResponse> handleUnhandledException(final Exception e) {
log.error("[ERROR]", e);
log.warn(LOG_FORMAT, e.getClass().getSimpleName(), INTERNAL_SERVER_ERROR.getValue(), e.getMessage());
return ResponseEntity.internalServerError()
.body(ExceptionResponse.from(INTERNAL_SERVER_ERROR_MESSAGE, INTERNAL_SERVER_ERROR));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.woowacourse.f12.presentation;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;

@Slf4j
@Component
public class LogInterceptor implements HandlerInterceptor {

private static final String REQUEST_LOG_FORMAT = "METHOD: {}, URL : {}, AUTHORIZATION : {}, BODY : {}";
private static final String RESPONSE_LOG_FORMAT = "STATUS_CODE: {}, BODY : {}";

@Override
public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler)
throws Exception {
final String body = new String(new ContentCachingRequestWrapper(request).getContentAsByteArray());
log.info(REQUEST_LOG_FORMAT, request.getMethod(), request.getRequestURI(), request.getHeader("Authorization"),
body);
return true;
}

@Override
public void afterCompletion(final HttpServletRequest request, final HttpServletResponse response,
final Object handler, final Exception ex)
throws Exception {
final ContentCachingResponseWrapper contentCachingResponseWrapper = new ContentCachingResponseWrapper(response);
final String responseBody = new String(contentCachingResponseWrapper.getContentAsByteArray());
log.info(RESPONSE_LOG_FORMAT, response.getStatus(), responseBody);
}
}
7 changes: 7 additions & 0 deletions backend/src/main/resources/application-local.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
spring:
config:
import:
- classpath:/submodules/application-auth.yml
- classpath:/submodules/application-h2.yml
logging:
config: classpath:log4j2/log4j2-local.xml
7 changes: 7 additions & 0 deletions backend/src/main/resources/application-main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
spring:
config:
import:
- classpath:/submodules/application-auth.yml
- classpath:/submodules/application-h2.yml
logging:
config: classpath:log4j2/log4j2-main.xml
7 changes: 7 additions & 0 deletions backend/src/main/resources/application-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
spring:
config:
import:
- classpath:/submodules/application-auth.yml
- classpath:/submodules/application-h2.yml
logging:
config: classpath:log4j2/log4j2-release.xml
10 changes: 6 additions & 4 deletions backend/src/main/resources/application.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
spring:
config:
import:
- classpath:/submodules/application-auth.yml
- classpath:/submodules/application-h2.yml
profiles:
group:
main:
release:
local:
default: local
jpa:
hibernate:
ddl-auto: none
Expand Down
25 changes: 25 additions & 0 deletions backend/src/main/resources/log4j2/log4j2-local.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns="http://logging.apache.org/log4j/2.0/config">
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %t %class{36}.%M L:%L %m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="com.woowacourse.f12" level="debug" additivity="false">
<AppenderRef ref="ConsoleAppender"/>
</Logger>
<Logger name="com.springframework" level="debug" additivity="false">
<AppenderRef ref="ConsoleAppender"/>
</Logger>
<Logger name="org.hibernate.SQL" level="debug" additivity="false">
<AppenderRef ref="ConsoleAppender"/>
</Logger>
<Logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="debug" additivity="false">
<AppenderRef ref="ConsoleAppender"/>
</Logger>
<Root level="error">
<AppenderRef ref="ConsoleAppender"/>
</Root>
</Loggers>
</Configuration>
57 changes: 57 additions & 0 deletions backend/src/main/resources/log4j2/log4j2-main.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Properties>
<Property name="log">logs/log/log</Property>
<Property name="db-log">logs/db/db</Property>
<Property name="log-pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %t %class{36}.%M L:%L %m%n</Property>
<Property name="file-pattern">%d{yyyy-MM-dd}-%i.log.gz</Property>
</Properties>
<Appenders>
<RollingFile name="FileAppender" fileName="${log}.log" filePattern="${log}-${file-pattern}"
immediateFlush="false">
<PatternLayout pattern="${log-pattern}"/>
<Policies>
<SizeBasedTriggeringPolicy size="15MB"/>
<TimeBasedTriggeringPolicy modulate="true" interval="1"/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${log}" maxDepth="1">
<IfLastModified age="30d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<RollingFile name="DbAppender" fileName="${db-log}.log" filePattern="${db-log}-${file-pattern}"
immediateFlush="false">
<PatternLayout pattern="${log-pattern}"/>
<Policies>
<SizeBasedTriggeringPolicy size="15MB"/>
<TimeBasedTriggeringPolicy modulate="true" interval="1"/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${db-log}" maxDepth="1">
<IfLastModified age="30d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>

</Appenders>
<Loggers>
<AsyncLogger name="com.woowacourse.f12" level="info" additivity="false" includeLocation="true">
<AppenderRef ref="FileAppender"/>
</AsyncLogger>
<AsyncLogger name="com.springframework" level="info" additivity="false" includeLocation="true">
<AppenderRef ref="FileAppender"/>
</AsyncLogger>
<AsyncLogger name="org.hibernate.SQL" level="debug" additivity="false" includeLocation="true">
<AppenderRef ref="DbAppender"/>
</AsyncLogger>
<AsyncLogger name="org.hibernate.type.descriptor.sql.BasicBinder" level="trace" additivity="false"
includeLocation="true">

<AppenderRef ref="DbAppender"/>
</AsyncLogger>
<Root level="error">
<AppenderRef ref="FileAppender"/>
</Root>
</Loggers>
</Configuration>
57 changes: 57 additions & 0 deletions backend/src/main/resources/log4j2/log4j2-release.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Properties>
<Property name="log">logs/log/log</Property>
<Property name="db-log">logs/db/db</Property>
<Property name="log-pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %t %class{36}.%M L:%L %m%n</Property>
<Property name="file-pattern">%d{yyyy-MM-dd}-%i.log.gz</Property>
</Properties>
<Appenders>
<RollingFile name="FileAppender" fileName="${log}.log" filePattern="${log}-${file-pattern}"
immediateFlush="false">
<PatternLayout pattern="${log-pattern}"/>
<Policies>
<SizeBasedTriggeringPolicy size="15MB"/>
<TimeBasedTriggeringPolicy modulate="true" interval="1"/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${log}" maxDepth="1">
<IfLastModified age="7d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<RollingFile name="DbAppender" fileName="${db-log}.log" filePattern="${db-log}-${file-pattern}"
immediateFlush="false">
<PatternLayout pattern="${log-pattern}"/>
<Policies>
<SizeBasedTriggeringPolicy size="15MB"/>
<TimeBasedTriggeringPolicy modulate="true" interval="1"/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${db-log}" maxDepth="1">
<IfLastModified age="7d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>

</Appenders>
<Loggers>
<AsyncLogger name="com.woowacourse.f12" level="debug" additivity="false" includeLocation="true">
<AppenderRef ref="FileAppender"/>
</AsyncLogger>
<AsyncLogger name="com.springframework" level="debug" additivity="false" includeLocation="true">
<AppenderRef ref="FileAppender"/>
</AsyncLogger>
<AsyncLogger name="org.hibernate.SQL" level="debug" additivity="false" includeLocation="true">
<AppenderRef ref="DbAppender"/>
</AsyncLogger>
<AsyncLogger name="org.hibernate.type.descriptor.sql.BasicBinder" level="trace" additivity="false"
includeLocation="true">

<AppenderRef ref="DbAppender"/>
</AsyncLogger>
<Root level="error">
<AppenderRef ref="FileAppender"/>
</Root>
</Loggers>
</Configuration>
14 changes: 3 additions & 11 deletions backend/src/test/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,13 @@ spring:
jpa:
hibernate:
ddl-auto: create
show-sql: true
properties:
hibernate:
format_sql: true

server:
port: 8888

logging:
level:
org:
hibernate:
sql: debug
type:
descriptor:
sql:
BasicBinder: trace

github:
client:
id: clientId
Expand All @@ -32,3 +21,6 @@ security:
jwt:
secret-key: testfkjasl123jl1kjdklfha2h3eoi1eojqdoiq112lkdldk
expire-length: 3600000

logging:
config: classpath:log4j2/log4j2-local.xml