Tirtha
Tirtha

Reputation: 145

CXF logging Interceptors

I am currently logging CXF using log4j as mentioned in CXF user guide. But the log file is flooding and becoming unmanageable with all IN/OUT payload logs.

I need to log incoming SOAP payload only when some fault/exception is generated as output. I understand that it will require to write custom interceptor, but is this possible to achieve?

Can anybody provide me some link/hint or may be some example working piece of code?

Thanks in Advance Tirthankar

Upvotes: 3

Views: 7965

Answers (2)

Halil
Halil

Reputation: 2297

You need a custom Feature to only log SOAP fault/exception.

Following is the source code of LoggingFeature.initializeProvider() method. As you can see, fault interceptors are being added inside this method.

@Override
protected void initializeProvider(InterceptorProvider provider, Bus bus) {
    if (limit == DEFAULT_LIMIT && inLocation == null 
        && outLocation == null && !prettyLogging) {
        provider.getInInterceptors().add(IN);
    >>> provider.getInFaultInterceptors().add(IN);
        provider.getOutInterceptors().add(OUT);
    >>> provider.getOutFaultInterceptors().add(OUT);
    } else {
        LoggingInInterceptor in = new LoggingInInterceptor(limit);
        in.setOutputLocation(inLocation);
        in.setPrettyLogging(prettyLogging);
        in.setShowBinaryContent(showBinary);
        LoggingOutInterceptor out = new LoggingOutInterceptor(limit);
        out.setOutputLocation(outLocation);
        out.setPrettyLogging(prettyLogging);
        out.setShowBinaryContent(showBinary);

        provider.getInInterceptors().add(in);
        provider.getInFaultInterceptors().add(in);
        provider.getOutInterceptors().add(out);
        provider.getOutFaultInterceptors().add(out);
    }
}

You can write your own LoggingFeature and override initializeProvider as follows:

public class CustomLoggingFeature extends LoggingFeature {
    @Override
    protected void initializeProvider(InterceptorProvider provider, Bus bus) {
        provider.getInFaultInterceptors().add(new LoggingInInterceptor(getLimit()));
        provider.getOutFaultInterceptors().add(new LoggingOutInterceptor(getLimit()));
    }
}

Then you may activate CustomLoggingFeature as follows:

@WebService
@Features(classes = {CustomLoggingFeature.class})
public interface AssetServices {
}

Upvotes: 0

alamnr
alamnr

Reputation: 41

This link may help : http://www.madbit.org/blog/programming/942/how-to-log-apache-cxf-soap-request-and-response-using-log4j/#sthash.SOlB7sx6.CaTMsv3I.dpbs

You can do it by writing a custom interceptor and add bean ref as follows in your cxf.xml file :

<bean id="customIncomingSoapFaultInterceptor"     class="com.tirtha.CustomIncomingSoapFaultInterceptor" />

<cxf:bus>

    <cxf:inFaultInterceptors>
        <ref bean="customIncomingSoapFaultInterceptor" />

    </cxf:inFaultInterceptors>

</cxf:bus>

Sample custom interceptor:

import java.io.IOException;
import java.io.InputStream;
import javax.servlet.http.HttpServletRequest;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.cxf.binding.soap.Soap12;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.transport.http.AbstractHTTPDestination;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class CustomIncomingSoapFaultInterceptor extends AbstractSoapInterceptor  {

private static Log s_logger =    LogFactory.getLog(CustomIncomingSoapFaultInterceptor.class);


public CustomIncomingSoapFaultInterceptor(){

    // set phase here
    //super(Phase.PRE_PROTOCOL);
    super(Phase.RECEIVE);
}
@Override
public void handleMessage(SoapMessage message) throws Fault {
    Fault fault = null;
    String soapMessage = null;

        StringBuilder strMessage = null;    
        HttpServletRequest httpRequest = (HttpServletRequest) message.get(AbstractHTTPDestination.HTTP_REQUEST);
        if (httpRequest != null) {


             InputStream ist = message.getContent(InputStream.class);
                if (ist != null) {
                    CachedOutputStream bos = new CachedOutputStream();
                    try {
                        IOUtils.copy(ist, bos);

                        bos.flush();
                        ist.close();
                        message.setContent(InputStream.class, bos.getInputStream());
                        soapMessage = new String(bos.getBytes());//this soap message is what you want
                        bos.close();

                        s_logger.debug("Soap Message: ---------->" + soapMessage==null?"null":soapMessage);
                        s_logger.debug("String Request: ---------->" + soapMessage);


                    } catch (IOException e) {
                        throw new Fault(e);
                    }
                }



        }
}

Upvotes: 4

Related Questions