入力として複数のエンティティ ID を持つ Web サービスに MDC を実装する問題に直面しており、このサービスは 1 つずつ外部サービスにヒットします。そのため、個別のエンティティ ID ごとに 1 つのスレッドを作成し、すべての返信を収集しました。各トランザクションのログ エントリをアウト サービスから外部サービスにリンクすることは非常に困難です。これに対処するために、MDC を導入しました。問題は、http 要求が新しい correlationId を取得しているのに、内部スレッドが最初の correlationId のままになっていることです。MDC を実装するために、次のフィルターを作成しました。
import java.io.IOException;
import java.util.UUID;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
@WebFilter(filterName = "correlationIdFilter", urlPatterns = { "/*" })
public class CorrelationIdFilter implements Filter {
public static final String DEFAULT_CORRELATION_ID_HEADER_NAME = "requestCorrelationId";
public static final String INIT_PARM_CORRELATION_ID_HEADER = "correlation.id.header";
private static final Logger LOGGER = LoggerFactory.getLogger(CorrelationIdFilter.class);
private String correlationHeaderName;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
String headerName = filterConfig.getInitParameter(INIT_PARM_CORRELATION_ID_HEADER);
if (StringUtils.isEmpty(headerName)) {
correlationHeaderName = DEFAULT_CORRELATION_ID_HEADER_NAME;
} else {
correlationHeaderName = headerName.trim();
}
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException
{
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String correlationId = httpServletRequest.getHeader(correlationHeaderName);
if (StringUtils.isEmpty(correlationId)) {
correlationId = UUID.randomUUID().toString();
MDC.put("correlationId", correlationId);
}
LOGGER.info(MDC.get("correlationId"));
try {
chain.doFilter(request, response);
} finally {
MDC.clear();
}
}
public void destroy() {
// NoOp
}
}
サンプルログ:
最初の試み:
[2015-09-11 15:35:05,466] [Default Executor-thread-33][DEBUG][XXXXXXXXXXXXXXXXXXXXXXXXXX] 941ded25-3041-47e2-915d-48ff65758f8d - Performance of XXXXXXXXXXXXXXXXXXXXXXXXXX for one Entity- 1111 size : 357 ms [2015-09-11 15:35:05,466] [Default Executor-thread-34][DEBUG][XXXXXXXXXXXXXXXXXXXXXXXXXX] 941ded25-3041-47e2-915d-48ff65758f8d - Performance of XXXXXXXXXXXXXXXXXXXXXXXXXX for one Entity- 1112 size : 364 ms [2015-09-11 15:35:05,468] [Default Executor-thread-17][DEBUG][XXXXXXXXXXXXXXXXXXXXXXXXXX] 941ded25-3041-47e2-915d-48ff65758f8d - Performance of XXXXXXXXXXXXXXXXXXXXXXXXXX for one Entity- 1113 size : 383 ms [2015-09-11 15:35:05,469] [Default Executor-thread-56][DEBUG][XXXXXXXXXXXXXXXXXXXXXXXXXX] 941ded25-3041-47e2-915d-48ff65758f8d - Performance of XXXXXXXXXXXXXXXXXXXXXXXXXX for one Entity- 1114 size : 395 ms [2015-09-11 15:35:05,471] [Default Executor-thread-61][DEBUG][XXXXXXXXXXXXXXXXXXXXXXXXXX] - Performance of XXXXXXXXXXXXXXXXXXXXXXXXXX for one Entity- 1115 size : 369 ms [2015-09-11 15:35:05,478] [Default Executor-thread-13][DEBUG][Service] 941ded25-3041-47e2-915d-48ff65758f8d - Performance of getEntryTotalsPeriod service for 5 Entities : 9986 ms
2 回目の試行
[2015-09-11 15:36:22,616] [Default Executor-thread-34][DEBUG][XXXXXXXXXXXXXXXXXXXXXXXXXX] 941ded25-3041-47e2-915d-48ff65758f8d - Performance of XXXXXXXXXXXXXXXXXXXXXXXXXX for one Entity- 1111 size : 431 ms [2015-09-11 15:36:22,627] [Default Executor-thread-41][DEBUG][XXXXXXXXXXXXXXXXXXXXXXXXXX] 941ded25-3041-47e2-915d-48ff65758f8d - Performance of XXXXXXXXXXXXXXXXXXXXXXXXXX for one Entity- 1112 size : 427 ms [2015-09-11 15:36:22,630] [Default Executor-thread-29][DEBUG][XXXXXXXXXXXXXXXXXXXXXXXXXX] 941ded25-3041-47e2-915d-48ff65758f8d - Performance of XXXXXXXXXXXXXXXXXXXXXXXXXX for one Entity- 1113 size : 403 ms [2015-09-11 15:36:22,634] [Default Executor-thread-16][DEBUG][XXXXXXXXXXXXXXXXXXXXXXXXXX] 941ded25-3041-47e2-915d-48ff65758f8d - Performance of XXXXXXXXXXXXXXXXXXXXXXXXXX for one Entity- 1114 size : 302 ms [2015-09-11 15:36:22,634] [Default Executor-thread-15][DEBUG][XXXXXXXXXXXXXXXXXXXXXXXXXX] 941ded25-3041-47e2-915d-48ff65758f8d - Performance of XXXXXXXXXXXXXXXXXXXXXXXXXX for one Entity- 1115 size : 315 ms [2015-09-11 15:36:22,642] [Default Executor-thread-49][DEBUG][Service] 6360d4c6-5330-4f7d-ac3a-06e5d75f73d5 - Performance of service for 5 Entities : 5372 ms
最後の行は http からのもので、correlationId が変更されていますが、常に同じ相関 ID である子マルチスレッド サービス呼び出しではありません。
この問題を解決するのを手伝ってください。