我有一个中间件 java spring 应用程序,它在顶层发布服务,并在底层有 Axis 2 客户端用于服务消费。当在服务层发出请求时,使用 MDC (log4j 1.x) 将会话 ID 添加到线程上下文中。
我们来自服务层(顶部)和集成层(底部)的所有日志记录都使用 MDC 输出会话 id,因此可以关联这些日志。
困难是我还需要为axis2客户端输出请求和响应xml。我创建了以下处理程序来完成此操作:
public class AxisXmlLoggerHandler extends AbstractHandler {
static Logger log = LoggerFactory.getLogger("xmlLogger");
@Override
public InvocationResponse invoke(MessageContext mc) throws AxisFault {
log.info(mc.getEnvelope().toString());
return InvocationResponse.CONTINUE;
}
}
还在 InFlow、InFaultFlow、OutFlow、OutFaultFlow 中将此添加到 axis2.xml
<handler name="XMLLoggerDispatcher" class="com.xxx.xxx.logging.AxisXmlLoggerHandler"/>
这对于记录 xml 非常有效,但是会话 ID 不在 MDC 中,我假设是因为 MDC 被复制到子线程并且处理程序是从不同的池中执行的。
所以我面临的问题是,如何让 MDC 进入处理程序线程?
虽然我真正需要的是会话 ID,但也许还有其他选择。例如,我们在传出标头上添加会话 ID,所以我想如果我可以从处理程序访问标头,并找到一种通过其他机制(自定义生命周期)关联请求和响应消息的方法,那也可以解决我的问题。但是,我无法在处理程序的肥皂信封中找到任何标题。我从处理程序类中尝试了以下两种方式:
Iterator<SOAPHeader> hi = mc.getEnvelope().getHeader().examineAllHeaderBlocks();
if (!hi.hasNext()) log.info("no headers using examineAllHeaderBlocks");
while (hi.hasNext()) {
SOAPHeader header = hi.next();
log.info("header: "+header.getLocalName()+" "+header.getText()+" string: "+header.toString());
}
Iterator<OMElement> i = (Iterator<OMElement>) mc.getEnvelope().getHeader().getChildElements();
if (!i.hasNext()) log.info("no headers using getChildElements");
while (i.hasNext()) {
OMElement test = i.next();
log.info("header child: "+test.getText());
}
在这两种情况下,日志都没有显示标题。我还尝试在没有影响的情况下转移到流程中的不同阶段。任何帮助将不胜感激