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?

+3


source to share


2 answers


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 {}
}

      

+2


source


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.

+2


source







All Articles