Журнал MDC с реактором с использованием logOnNext

#logging #reactor-netty #mdc #spring-boot-2

#ведение журнала #реактор-нетти #mdc #spring-boot-2

Вопрос:

Мне нужно показывать значения контекста в журналах всего приложения. Я пытался сделать это с помощью этого метода: «searchStudents», но я не добился успеха. Кажется, что при выполнении шага «.doOnComplete ()» subscriberContext теряется, и мне нужна альтернатива. У кого-нибудь есть какое-то решение, чтобы предложить мне??

Контроллер

 @GetMapping(value = "{userId}/searchStudents")
public Flux<Student> searchStudents(
        @ModelAttribute(USER_CONTEXT_REQUEST_ATTRIBUTE) Context userContext,
        @PathVariable String userId, 
        @RequestParam String lang, 
        @RequestParam String studentName) {
    return coursesProvider.searchStudents(userId, lang, studentName).subscriberContext(userContext);
  

logUtils

 public class LogUtils {
    public static <T> Consumer<Signal<T>> logOnNext(Consumer<T> logStatement) {
        return signal -> {
            if (!signal.isOnNext()) 
                return;
        
        Optional<String> teacherIdMaybe = signal.getContext().getOrEmpty("TEACHER_ID");
            
        if (teacherIdMaybe.isPresent()) {
            try (MDC.MDCCloseable teacherIdMdcCloseable = MDC.putCloseable("TEACHER_ID", teacherIdMaybe.get())) {
                logStatement.accept(signal.get());
            }
        } else {
            logStatement.accept(signal.get());
        };
    };
}
  

}

Обслуживание

     @Override
    public Flux<Student> searchStudents(String userId, String lang, String studentName) {
        AtomicInteger counter = new AtomicInteger(); 
        return Mono.just(String.format(">>> Searching student named: %s. <<<", studentName))
                .doOnEach(logOnNext(LOGGER::info))   // well logged
                .thenMany(webClient.get()
                        .uri(uriBuilder -> uriBuilder
                                .path("/v1/users/{userId}/courses/searchStudents/{lang}/{studentName}")
                                .build(userId, lang, studentName))
                        .accept(APPLICATION_JSON)
                        .retrieve()
                        .bodyToFlux(Student.class)
                        .filter(Student::isEligible)
                        .doOnNext(p -> counter.incrementAndGet())
                        
                        // this is the ligne that I need to change
                        .doOnComplete(() -> LOGGER.info("{} students found", counter.get())) 
                );
    }
  

Мои попытки:

  1. Возвращает поток строк

.затем( Mono.just(String.format(«% студентов найдено», counter.get())) .doOnEach(logOnNext(LOGGER::info)))

  1. Нет журнала
 .doOnComplete(() -> Mono.just(String.format("%s students found", counter.get()))
.doOnEach(logOnNext(LOGGER::info))
.then() // no log
.subscribe() // log without MDC
)
  
  1. Каждый счет регистрируется, и я хочу окончательный подсчет
 .doOnEach(logOnNext( x -> LOGGER.info("{} students found", counter.get()))
  

Комментарии:

1. вы решили эту проблему?

2. @DarthVader пока нет!!