我需要在整个应用程序的日志中显示上下文值。我试图用这种方法做到这一点:“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);
日志工具
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()))
);
}
我的尝试:
- 返回一个 Flux 字符串
.then( Mono.just(String.format("%s 个学生找到", counter.get())) .doOnEach(logOnNext(LOGGER::info)))
- 无日志
.doOnComplete(() -> Mono.just(String.format("%s students found", counter.get())) .doOnEach(logOnNext(LOGGER::info)) .then() // no log .subscribe() // log without MDC )
- 记录每个计数,我想要最终计数
.doOnEach(logOnNext( x -> LOGGER.info("{} students found", counter.get()))