Home Error 로그 기록
Post
Cancel

Error 로그 기록


기존 프로젝트에 로그 설정하기

  • 로그 관리 시스템을 추가.
    • 기능 1 ] 하나의 요청과 응답을 묶어 UUID를 부여하기.
    • 기능 2 ] error 로그 파일로 적재하기
    • 기능 3 ] 로그 추적에 편리함을 주기 위해 요청의 실패 성공 여부를 DB에 적재
    • 기능 4 ] 에러가난 요청의 UUID를 에러 파일에서 찾아서 대응 가능.


요청과 응답 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를 사용할 예정임으로 configfilter로 추가

  • 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로 묶여서 나오는걸 볼 수 있음.

trace_id


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의 로그를 기록하는 기능 구현이 완료된다.

error_file

This post is licensed under CC BY 4.0 by the author.