기존 프로젝트에 로그 설정하기
- 로그 관리 시스템을 추가.
- 기능 1 ] 하나의 요청과 응답을 묶어
UUID
를 부여하기. - 기능 2 ] error 로그 파일로 적재하기
- 기능 3 ] 로그 추적에 편리함을 주기 위해 요청의 실패 성공 여부를
DB
에 적재 - 기능 4 ] 에러가난 요청의
UUID
를 에러 파일에서 찾아서 대응 가능.
- 기능 1 ] 하나의 요청과 응답을 묶어
요청과 응답 UUID로 묶기
- 기본 설정된 콘솔에 띄워지는 로그는 해당 로그를 발생시킨 주체를
쓰레드
까지밖에 세분화를 못시킴
1
2
3
4
2024-03-07 16:53:10 [ http-nio-8080-exec-3 ] [ DEBUG] [i.s.v.c.c.ModelConverterContextImpl] - resolve int
2024-03-07 16:53:10 [ http-nio-8080-exec-3 ] [ DEBUG] [i.s.v.c.c.ModelConverterContextImpl] - resolve java.util.List<org.spring.oauth2.email_validate_register.user.dto.UserDto>
2024-03-07 16:53:10 [ http-nio-8080-exec-3 ] [ DEBUG] [i.s.v.c.c.ModelConverterContextImpl] - resolve [simple type, class org.spring.oauth2.email_validate_register.user.dto.UserDto]
2024-03-07 16:53:10 [ http-nio-8080-exec-3 ] [ DEBUG] [i.s.v.c.c.ModelConverterContextImpl] - resolve [simple type, class java.lang.String]
- 장애가 발생하였을때 더욱 디테일한 정보로 로그를 추적해야 하기 때문에
요청과 응답을
UUID
로 묶어 사용해야함- 이때 필요한게
MDC
- 이때 필요한게
MDC
: 쉽게 말하면 현재 실행중인 쓰레드에 메타정보를 넣고 관리하는 공간.- 내부적으로 Map을 관리하고 있어서 key:value 셋팅 가능
- 해당 메타정보에
UUID
를 추가하여logback-spring.xml
설정을 통해 콘솔에 노출.
MDC
MDC
클래스 내부 정보- 결론 : 아무튼
MDCAdapter
어뎁터에 key,value를 put 할 수 있다.
- 결론 : 아무튼
1
2
3
4
5
6
7
8
9
10
11
12
13
public class MDC {
// ....
public static void put(String key, String val) throws IllegalArgumentException {
if (key == null) {
throw new IllegalArgumentException("key parameter cannot be null");
}
if (mdcAdapter == null) {
throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
}
mdcAdapter.put(key, val);
}
// ....
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public interface MDCAdapter {
public void put(String key, String val);
public String get(String key);
public void remove(String key);
public void clear();
public Map<String, String> getCopyOfContextMap();
public void setContextMap(Map<String, String> contextMap);
public void pushByKey(String key, String value);
public String popByKey(String key);
public Deque<String> getCopyOfDequeByKey(String key);
public void clearDequeByKey(String key);
}
MDC 메타정보에 UUID 넣기
추후에
spring security
를 사용할 예정임으로config
에filter
로 추가MDCLoggingFilter
: 요청과 응답을UUID
로 묶어주고 마지막에 해당 메타정보 삭제- 하나의 요청당 한번만 실행되어야 함으로
OncePerRequestFilter
적용
- 하나의 요청당 한번만 실행되어야 함으로
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MDCLoggingFilter extends OncePerRequestFilter {
private static final String TRACE_ID = "traceId";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
String uuid = UUID.randomUUID().toString();
MDC.put(TRACE_ID, uuid);
filterChain.doFilter(request, response);
} finally {
MDC.remove(TRACE_ID);
}
}
}
security config
에 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Slf4j
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class WebSecurityConfig {
// ...
@Bean
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http
// ...
.addFilterAt(new MDCLoggingFilter(), BasicAuthenticationFilter.class)
// ...
return http.build();
}
// ...
}
UUID를 콘솔에서 출력되는 정보에 추가하기
logback-spring.xml
사용- 패턴을 지정해주는 부분에서
%X{traceId}]
와 같은 형식으로 MDC안에 있는 값을 꺼내올 수 있음 출력 패턴은 아래와 같음
- 패턴을 지정해주는 부분에서
1
%green(%d{yyyy-MM-dd HH:mm:ss}) %boldWhite([ %thread ]) %green([traceId : %X{traceId}]) %boldCyan([ %-5level]) %boldWhite([%logger{36}]) - %msg%n"
설정 후 콘솔 로그 출력 결과
- 아래의 메세지와 같이 쓰레드 오른쪽에 traceId 로 요청이
UUID
로 묶여서 나오는걸 볼 수 있음.
error 로그 파일에 적재하기
- 이전 구성이 완료 되었다면 에러 로그에 대한 파일 적재를 해야함
- 이때 콘솔에 보이는 로그는
INFO
레벨 이어야 하고 파일에 쌓이는 데이터는ERROR
레벨이어야함
- 이때 콘솔에 보이는 로그는
- 파일 어펜더를 설정할때 filter를 끼어넣어
ERROR
레벨에서만 파일에 적재하게 설정 변경- LevelFilter : 에러 레벨에 따른 처리를 할 수 있게 해주는 클래스
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>...</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>error</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
...
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
...
</rollingPolicy>
</appender>
...
<root level="INFO">
<appender-ref ref="CONSOLE_INFO"/>
<appender-ref ref="FILE_ERROR"/>
</root>
- 위와같이 설정하면 아래와같이 콜솔에는
INFO
파일에는ERROR
의 로그를 기록하는 기능 구현이 완료된다.