How to Override Client Side Soap Log - Spring Boot
I am using a soap webservice inside a spring boot application. Response / request logging is too large due to one attribute that is too large. So I want to intercept this log and remove the offending attribute.
I've already fiddled with SoapEnvelopeLoggingInterceptor but I think this is just for server side logging. He will not be raised.
I configured my pit log like this:
logging:
pattern:
...
level:
...
org.springframework.ws.client.MessageTracing.sent: TRACE
org.springframework.ws.client.MessageTracing.received: TRACE
org.springframework.ws.server.MessageTracing: DEBUG
This is great for logging both request and response, but I need to remove a very large problematic attribute from the envelope. Any ideas?
source to share
You can create an implementation for ClientInterceptor
handleRequest
and handleResponse
for parsing, modifying, and logging your message.
The following code delegates AbstractLoggingInterceptor
handleRequest
and handleResponse
overrides logMessage
to create a custom message.
Something like
public class MyInterceptor implements ClientInterceptor {
private final Logger logger = LoggerFactory.getLogger(MyInterceptor.class);
private EndpointInterceptor endpointInterceptor = new AbstractLoggingInterceptor() {
@Override
protected Source getSource(WebServiceMessage webServiceMessage) {
// Base logic same as SoapEnvelopeLoggingInterceptor getSource method.You can adjust to your preference.
if(webServiceMessage instanceof SoapMessage) {
SoapMessage soapMessage = (SoapMessage)webServiceMessage;
return soapMessage.getEnvelope().getSource();
} else {
return null;
}
}
@Override
protected void logMessage(String message) {
// You can use your regex to remove the attribute and log the message.
this.logger.debug(message);
}
};
@Override
public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {
return endpointInterceptor.handleRequest(messageContext, null);
}
@Override
public boolean handleResponse(MessageContext messageContext) throws WebServiceClientException {
return endpointInterceptor.handleResponse(messageContext, null);
}
@Override
public boolean handleFault(MessageContext messageContext) throws WebServiceClientException {
return true;
}
@Override
public void afterCompletion(MessageContext messageContext, Exception e) throws WebServiceClientException {}
}
source to share
There is no easy way to do this. You, aether, implement your own Logger
sl4j extension API, or terminate log calls and do transformations there.
The first way will take some effort because you will need to implement a package of classes and make sure that other parts of the log system are not broken.
But the second part is pretty straight forward. You have tI create a bypass directory that implements the interface Logger
, maybe something like this:
public class LoggerWrapper extends MarkerIgnoringBase {
private final Logger logger;
public LoggerWrapper(Logger logger) {
this.logger = logger;
}
private String transformMessage(String input) {
// do all needed regexp transformations here
}
@Override
public void debug(String msg) {
String transformedMessage = transformMessage(msg);
// delegate log call to inner logger
logger.debug(transformedMessage);
}
// implement the rest of the methods here
}
And in code, you can use it like this:
private static final Logger log = new LoggerWrapper(
LoggerFactory.getLogger(SomeClass.class)
);
You can also wrap the log without implementing an interface Logger
(in my case it is a class MarkerIgnoringBase
). In this case, you will not need to inject many methods from the interface, but you will be interchangeable.
The downside to this solution is that you have to pre-register messages on your side (not through MessageTracing
), but if possible I would go that route. On the other hand, the first solution does it out of the box.
source to share