I think you should view the request input stream as consumed when handling the fault.
I suggest you always log the incoming message, and extract some kind of message correlation id - for example username. Keep it as a Message header.
For fault logging, use a fault interceptor which is limited to looking at the input request.
Tie regular + fault logging together with the message correlation id.
Log the full soap request, not just the payload. Soap requests might have headers in addition to the body.
See this question for regular logging, add in addition an output fault interceptor like so:
public class SoapFaultLoggingOutInterceptor extends AbstractPhaseInterceptor<Message> {
private static final String LOCAL_NAME = "MessageID";
private static final int PROPERTIES_SIZE = 128;
private String name = "<interceptor name not set>";
protected Logger logger = null;
protected Level level;
public SoapFaultLoggingOutInterceptor() {
this(LogUtils.getLogger(SoapFaultLoggingOutInterceptor.class), Level.WARNING);
}
public SoapFaultLoggingOutInterceptor(Logger logger, Level reformatSuccessLevel) {
super(Phase.MARSHAL);
this.logger = logger;
this.level = reformatSuccessLevel;
}
public void setName(String name) {
this.name = name;
}
public void handleMessage(Message message) throws Fault {
if (!logger.isLoggable(level)) {
return;
}
StringBuilder buffer = new StringBuilder(PROPERTIES_SIZE);
// perform local logging - to the buffer
buffer.append(name);
logProperties(buffer, message);
logger.log(level, buffer.toString());
}
/**
* Gets theMessageID header in the list of headers.
*
*/
protected String getIdHeader(Message message) {
return getHeader(message, LOCAL_NAME);
}
protected String getHeader(Message message, String name) {
List<Header> headers = (List<Header>) message.get(Header.HEADER_LIST);
if(headers != null) {
for(Header header:headers) {
if(header.getName().getLocalPart().equalsIgnoreCase(name)) {
return header.getObject().toString();
}
}
}
return null;
}
protected void logProperties(StringBuilder buffer, Message message) {
final String messageId = getIdHeader(message);
if(messageId != null) {
buffer.append(" MessageId=");
buffer.append(messageId);
}
Message inMessage = message.getExchange().getInMessage();
HttpServletRequest request = (HttpServletRequest)inMessage.get(AbstractHTTPDestination.HTTP_REQUEST);
buffer.append(" RemoteAddr=");
buffer.append(request.getRemoteAddr());
}
public Logger getLogger() {
return logger;
}
public String getName() {
return name;
}
public void setLogger(Logger logger) {
this.logger = logger;
}
}
where MessageID is the correlation / breadcrumb id.