我正在尝试通过使用特定属性填充
ThreadContext
并根据这些 attributes
过滤日志来实现动态调试日志记录。
这是我迄今为止所取得的成就:
在同一个 JVM 中:
contextWrite()
方法正确传递到所有反应式和非反应式流,并在链完成后清除。ExecutorService
,我将 Callable
包装在 ContextExecutorService
中来管理 ThreadContext。跨 JVM 的问题:
在分布式系统(例如 Hazelcast)中,当一个进程被提交到另一个 JVM 时,必须手动将上下文传递到一个字段中,并在目标的线程上下文中设置
JVM
。提交到另一个 JVM 的示例进程:
@Slf4j
public class LoggingEntryProcessor<K, V, R> implements EntryProcessor<K, V, R>, HazelcastInstanceAware {
private final EntryProcessor<K, V, R> processor;
private Map<String, String> attributes;
@Override
public R process(Entry<K, V> entry) {
// Ensure thread context is populated with attributes received from caller JVM and cleared after work is done
return processor.process(entry);
//the process method is nonreactive and may have reactive code inside of it.
}
private ContextSnapshot setContextSnapshot(Map<String, String> attributes) {
// tried creating a snapshot with which i can wrap, Slf4jThreadLocalAccessor is registered in ContextRegistry in this JVM
new Slf4jThreadLocalAccessor().setValue(attributes);
return ContextSnapshotFactory.builder().build().captureAll();
}
}
我尝试像这样包装流程调用:
try (Scope scope = contextSnapshot.setThreadLocals()) {
return processor.process(entry);
}
问题
问题
任何见解或例子将不胜感激!
我不确定这对你是否有帮助,但我有一个类似的问题,我想将信息传递给记录器,但我有一些信息通过 hazelcast,其他一些信息通过 ActiveMQ,我不操纵ThreadContext 我自己,但我依赖 Slf4j MDC (https://www.slf4j.org/api/org/slf4j/MDC.html),因为你可以轻松配置你的记录器来获取从它的信息来看,这个类有方法
getCopyOfContextMap()
和 setContextMap(Map<String,String> contextMap)
所以我只是发送一个映射作为 ActiveMQ 消息的一部分,并在它返回时更新它,这样一旦 activemq 返回,我在 MDC 对象的两侧都有相同的信息。