Mapped Diagnostic Context
logging spring java
MDC
The MDC is managed on a per thread basis. Use ThreadLocal.
package org.slf4j;
public class MDC {
// Put a context value as identified by key
// into the current thread's context map.
public static void put(String key, String val);
// Get the context identified by the key parameter
public static String get(String key);
// Remove the context identified by the key parameter
public static void remove(String key);
// Clear all entries in the MDC
public static void clear();
}
Support
- log4j, logback 만 지원하고 있음
Stamping each log request
하나의 요청(per thread) 안에서 로그를 100개 찍는다고 했을때, logstash, datadog 같은 곳에서 Grouping 하기 위한 구분값이 필요하다. 보통 그 구분 값을 TRACE-ID
라고 한다. 따라서, Log 에 TraceId 가 있으면 분산 시스템에서도 클라이언트를 구분할 수 있다.
- SimpleMDC
public class SimpleMDC {
static public void main(String[] args) throws Exception {
// You can put values in the MDC at any time. Before anything else
// we put the first name
MDC.put("first", "Dorothy");
Logger logger = LoggerFactory.getLogger(SimpleMDC.class);
// We now put the last name
MDC.put("last", "Parker");
// The most beautiful two words in the English language according
// to Dorothy Parker:
logger.info("Check enclosed.");
logger.debug("The most beautiful two words in English.");
MDC.put("first", "Richard");
MDC.put("last", "Nixon");
logger.info("I am not a crook.");
logger.info("Attributed to the former US president. 17 Nov 1973.");
}
}
// output
Dorothy Parker - Check enclosed.
Dorothy Parker - The most beautiful two words in English.
Richard Nixon - I am not a crook.
Richard Nixon - Attributed to the former US president. 17 Nov 1973.
CustomAppender
이러한 MDC 의 특징과 logback 의 Appender 클래스를 구현한 CustomAppender 를 이용하면 모든 로그에 TraceId 와 필요한 정보들을 같이 남길 수 있다.
@Slf4j
@Component
public class CustomConsoleAppender extends AsyncAppenderBase<ILoggingEvent> implements ApplicationContextAware {
private final ObjectMapper objectMapper;
public CustomConsoleAppender() {
objectMapper = new ObjectMapper();
super.addAppender(new AsyncAppender());
}
@Override
protected void append(ILoggingEvent iLoggingEvent) {
Map<String, String> messages = new HashMap<>();
messages.put("httpMethod", "POST");
messages.put("appVersion", "1");
// 생략
MDC.put("trace_id");
String logMessages = objectMapper.writeValueAsString(messages);
log.info("{}", logMessages);
MDC.remove("trace_id");
}
}