[자바] MDC
MDC
여러 클라이언트의 요청을 동시적으로 처리하는 서버에서 로그 출력을 수행할 때 하나의 요청에 대해 여러 로그가 출력될 수 있다. 요청에 대한 작업 수행이 동기적으로 일어나는 것이 아니라면 여러 요청에 대한 로그 출력이 동시 다발적으로 발생하는데 특정 요청에 대한 로그를 식별하는 것이 필요하다.
로깅 라이브러리는 특정 스레드가 로그 출력을 위해 접근이 필요한 데이터를 특정 요청과 매핑하기 위한 도구를 제공하며 MDC(mapped diagnostic congext)가 그 역할을 수행한다. MDC는 스레드 별로 생성되는 자료 구조이며, 해시 테이블(hash table) 자료 구조를 사용하여 컨텍스트 데이터를 키와 값 쌍으로 관리한다. 자바의 대표적인 로깅 프레임워크인 log4j, log4j2, sl4j, logback는 MDC를 위한 별도의 클래스 및 메서드를 제공한다.
MDC는 스레드 단위로 관리된다. MDC와 관련된 연산은 현재 스레드의 MDC에만 영향을 주며 다른 스레드의 MDC에는 영향을 주지 않는다. MDC는 내부적으로 스레드 별로 데이터를 저장 및 관리하는 ThreadLocal
을 사용한다.
멀티 스레드 환경에서는 하나의 요청을 여러 스레드가 처리하므로, 실행 컨텍스트(execution context) 데이터의 적절한 전파(propagation)가 중요하다. 비동기(asynchronous) 또는 리액티브(reactive) 프로그래밍에서는 요청 당 스레드 모델을 사용하여 요청에 대한 응답 처리를 하더라도 하나의 요청에 대한 작업을 여러 스레드가 수행하기 때문에 적절한 실행 컨텍스트 전파 메커니즘이 별도로 필요하다.
상속 관계에 있는 스레드의 경우 자식 스레드는 부모 스레드의 MDC 사본을 자동으로 상속받는다.
코틀린의 코루틴과 MDC
스프링의 요청 스코프와 MDC
참고
- https://www.slf4j.org/api/org/slf4j/MDC.html
- https://logging.apache.org/log4j/1.x/apidocs/org/apache/log4j/MDC.html
- https://dzone.com/articles/mdc-better-way-of-logging-1
- https://spring.io/blog/2023/03/28/context-propagation-with-project-reactor-1-the-basics
- https://simonbasle.github.io/2018/02/contextual-logging-with-reactor-context-and-mdc/
Comments