SpringBoot 프로젝트 에 MDC 로그 링크 추적 을 추가 하 는 실행 절차
12239 단어 SpringBootMDC로그링크 추적
여기에 사용
MDC
과ThreadLocal
은 각각 아래 의 가방 에서 제공 합 니 다.
java.lang.ThreadLocal
org.slf4j.MDC
직접 코드 올 리 기:1.스 레 드 탱크 설정
만약 에 수 동 으로 새 스 레 드 를 통 해 비동기 임 무 를 수행 하고 표지 전달 을 실현 하려 면 스스로 실현 해 야 합 니 다.사실은 스 레 드 탱크 와 마찬가지 로 호출
MDC
과 관련 된 방법 입 니 다.다음 과 같 습 니 다.
// MDC
Map<String, String> context = MDC.getCopyOfContextMap();
// MDC
MDC.setContextMap(context);
우선 상수 제공:
package com.example.demo.common.constant;
/**
*
*
* @author wangbo
* @date 2021/5/13
*/
public class Constants {
public static final String LOG_MDC_ID = "trace_id";
}
다음은ThreadPoolTaskExecutor
의 방법 을 다시 써 야 한다.
package com.example.demo.common.threadpool;
import com.example.demo.common.constant.Constants;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
/**
* MDC
*
*
* @author wangbo
* @date 2021/5/13
*/
@Slf4j
public class MdcTaskExecutor extends ThreadPoolTaskExecutor {
@Override
public <T> Future<T> submit(Callable<T> task) {
log.info("mdc thread pool task executor submit");
Map<String, String> context = MDC.getCopyOfContextMap();
return super.submit(() -> {
T result;
if (context != null) {
// MDC
MDC.setContextMap(context);
} else {
// MDC
MDC.put(Constants.LOG_MDC_ID, UUID.randomUUID().toString().replace("-", ""));
}
try {
//
result = task.call();
} finally {
try {
MDC.clear();
} catch (Exception e) {
log.warn("MDC clear exception", e);
}
}
return result;
});
}
@Override
public void execute(Runnable task) {
log.info("mdc thread pool task executor execute");
Map<String, String> context = MDC.getCopyOfContextMap();
super.execute(() -> {
if (context != null) {
// MDC
MDC.setContextMap(context);
} else {
// MDC
MDC.put(Constants.LOG_MDC_ID, UUID.randomUUID().toString().replace("-", ""));
}
try {
//
task.run();
} finally {
try {
MDC.clear();
} catch (Exception e) {
log.warn("MDC clear exception", e);
}
}
});
}
}
그 다음 에 사용자 정의 재 작성 서브 클래스MdcTaskExecutor
를 사용 하여 스 레 드 풀 설정 을 실현 합 니 다.
package com.example.demo.common.threadpool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
*
*
* @author wangbo
* @date 2021/5/13
*/
@Slf4j
@Configuration
public class ThreadPoolConfig {
/**
*
* , MDC
*/
@Bean
public Executor commonThreadPool() {
log.info("start init common thread pool");
//ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
MdcTaskExecutor executor = new MdcTaskExecutor();
//
executor.setCorePoolSize(10);
//
executor.setMaxPoolSize(20);
//
executor.setQueueCapacity(3000);
//
executor.setKeepAliveSeconds(120);
//
executor.setThreadNamePrefix("common-thread-pool-");
//
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
//
executor.initialize();
return executor;
}
/**
*
* , MDC , , MDC
* ,
*/
@Bean
public Executor scheduleThreadPool() {
log.info("start init schedule thread pool");
MdcTaskExecutor executor = new MdcTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(3000);
executor.setKeepAliveSeconds(120);
executor.setThreadNamePrefix("schedule-thread-pool-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
executor.initialize();
return executor;
}
}
2.차단기 설정
package com.example.demo.common.interceptor;
import com.example.demo.common.constant.Constants;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;
/**
*
*
* @author wangbo
* @date 2021/5/13
*/
@Slf4j
@Component
public class LogInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//log.info(" LogInterceptor");
// MDC
MDC.put(Constants.LOG_MDC_ID, UUID.randomUUID().toString().replace("-", ""));
//
String method = request.getMethod();
String uri = request.getRequestURI();
log.info("[ ] : {} : {}", method, uri);
//
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//log.info(" LogInterceptor");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//log.info(" LogInterceptor");
//
// MDC
MDC.remove(Constants.LOG_MDC_ID);
}
}
차단기 등록:
package com.example.demo.common.config;
import com.example.demo.common.interceptor.LogInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* MVC
*
* @author wangbo
* @date 2021/5/13
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private LogInterceptor logInterceptor;
/**
*
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(logInterceptor);
}
}
3.로그 파일 설정logback-spring.xml
파일 의 로그 인쇄 형식 에 추가 해 야 합 니 다%X{trace_id}
.다음 과 같 습 니 다.
<!-- -->
<appender name="console_out" class="ch.qos.logback.core.ConsoleAppender">
<!-- -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{trace_id}] [%level] [%thread] [%class:%line] - %m%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
4.사용 방법 예시4.1 비동기 사용
여기 서 비동기 방법의 호출 은 현재 클래스 의 방법 을 직접 호출 할 수 없습니다.즉,호출 방법 과 비동기 방법 은 같은 클래스 에 있 을 수 없습니다.그렇지 않 으 면 동기 화 실행 으로 변 할 수 있 습 니 다.
/**
*
*/
//@Async// , , , SimpleAsyncTaskExecutor
@Async(value = "commonThreadPool")//
@Override
public void async() {
log.info(" ");
}
4.2 정시 임무
package com.example.demo.generator.crontab;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
*
*
* @author wangbo
* @date 2021/5/14
*/
@Slf4j
@Component
public class TestTimeTask {
// @Scheduled , , 。
// taskScheduler, ID scheduling-x
// @Async , ( )。
/**
* 2S
* , 4S。 2S , ,
* , , 2S
*/
//@Async(value = "scheduleThreadPool")
//@Scheduled(fixedRate = 2000)
public void fixedRate() {
log.info(" fixedRate = {}", LocalDateTime.now());
try {
Thread.sleep(4_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 2S
* , , 6S。
* ,
*/
//@Scheduled(fixedDelay = 2_000)
public void fixedDelay() {
log.info(" fixedDelay = {}", LocalDateTime.now());
try {
Thread.sleep(4_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 10S fixedDelay , fixedDelay
*
* {@link # fixeddrate} or {@link #fixedDelay}
*/
//@Scheduled(initialDelay = 10_000, fixedDelay = 1_000)
public void initialDelay() {
log.info(" initialDelay = {}", LocalDateTime.now());
}
/**
* ,
*/
//@Async(value = "scheduleThreadPool")
//@Scheduled(cron = "0/2 * * * * *")
public void testCron() {
log.info(" testCron = {}", LocalDateTime.now());
try {
Thread.sleep(4_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
SpringBoot 프로젝트 에 MDC 로그 링크 추적 을 추가 하 는 글 을 소개 합 니 다.더 많은 SpringBoot MDC 로그 링크 추적 내용 은 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 도 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【Java・SpringBoot・Thymeleaf】 에러 메세지를 구현(SpringBoot 어플리케이션 실천편 3)로그인하여 사용자 목록을 표시하는 응용 프로그램을 만들고, Spring에서의 개발에 대해 공부하겠습니다 🌟 마지막 데이터 바인딩에 계속 바인딩 실패 시 오류 메시지를 구현합니다. 마지막 기사🌟 src/main/res...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.