A Guide to Configuring Apache CXF SOAP Request and Response Logging with Log4j

Dec 07, 2025 · Programming · 10 views · 7.8

Keywords: Apache CXF | Log4j | SOAP logging

Abstract: This article provides a detailed guide on configuring Apache CXF to log SOAP requests and responses using Log4j instead of the default console output. By creating specific configuration files and utilizing custom interceptors, developers can achieve persistent log storage and formatted output. Based on the best-practice answer and supplemented with alternative methods, it offers complete configuration steps and code examples to help readers deeply understand the integration of CXF logging mechanisms with Log4j.

Introduction

Apache CXF is a widely-used open-source web services framework supporting SOAP and RESTful services. During development and debugging, logging SOAP requests and responses is crucial for monitoring and troubleshooting. By default, CXF uses java.util.logging to output logs to the console, but in production environments, it is often necessary to persist logs to files, such as with Log4j. Based on community Q&A data, this article elaborates on how to configure CXF to use Log4j for logging SOAP messages and optimize log formatting.

Problem Context

In CXF client programs, developers typically add LoggingInInterceptor and LoggingOutInterceptor to log inbound and outbound messages. For example, using the following code:

JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setAddress(host);
factory.setServiceClass(MyService.class);
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());

This outputs SOAP messages to the console in a format like:

Nov 9, 2011 6:48:01 PM org.apache.cxf.interceptor.LoggingOutInterceptor$LoggingCallback onClose
INFO: Outbound Message
---------------------------
ID: 2
Encoding: UTF-8
Content-Type: text/xml
Headers: {}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns4:MYResponse

However, the actual requirement is to write logs to a file instead of the console. Directly configuring with Log4j might only output boolean values, such as true, thus requiring proper configuration of CXF to integrate with Log4j.

Core Configuration Method

According to the best answer, the main step is to create a configuration file to specify that CXF uses Log4j as the logging implementation. First, create a file at /META-INF/cxf/org.apache.cxf.Logger in the classpath with the content:

org.apache.cxf.common.logging.Log4jLogger

This instructs CXF to use Log4j instead of the default java.util.logging. Referring to the CXF official documentation, this method ensures log output is redirected to files configured in Log4j.

Optimizing Log Format

Beyond basic configuration, log output can be beautified through custom interceptors. Replace the standard CXF configuration:

<cxf:bus>
  <cxf:features>
    <cxf:logging/>
  </cxf:features>
</cxf:bus>

With a more verbose configuration to enable formatting of XML messages:

<bean id="abstractLoggingInterceptor" abstract="true">
    <property name="prettyLogging" value="true"/>
</bean>
<bean id="loggingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" parent="abstractLoggingInterceptor"/>
<bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor" parent="abstractLoggingInterceptor"/>

<cxf:bus>
    <cxf:inInterceptors>
        <ref bean="loggingInInterceptor"/>
    </cxf:inInterceptors>
    <cxf:outInterceptors>
        <ref bean="loggingOutInterceptor"/>
    </cxf:outInterceptors>
    <cxf:outFaultInterceptors>
        <ref bean="loggingOutInterceptor"/>
    </cxf:outFaultInterceptors>
    <cxf:inFaultInterceptors>
        <ref bean="loggingInInterceptor"/>
    </cxf:inFaultInterceptors>
</cxf:bus>

This sets the prettyLogging property to true, formatting XML messages with indentation and line breaks for better readability. This configuration is suitable for Spring contexts, ensuring all interceptors apply beautified logging.

Supplementary Method

Another convenient approach is to set the logger class in the client constructor, ensuring execution before loading CXF-related classes. For example:

YourClientConstructor() {
  LogUtils.setLoggerClass(org.apache.cxf.common.logging.Log4jLogger.class);
  URL wsdlURL = YOurURL;
  YourService = new YourService(wsdlURL, SERVICE_NAME);
  port = yourService.getServicePort(); 
  Client client = ClientProxy.getClient(port);
  client.getInInterceptors().add(new LoggingInInterceptor());
  client.getOutInterceptors().add(new LoggingOutInterceptor());
}

This dynamically specifies the logging implementation via LogUtils.setLoggerClass, then adds interceptors. Note that this method requires proper Log4j configuration, such as defining file output in log4j.properties or log4j2.xml.

Conclusion

By creating the org.apache.cxf.Logger configuration file, CXF can seamlessly integrate with Log4j, redirecting SOAP logs from the console to files. Combined with custom interceptor configurations, formatted log output can be achieved, enhancing debugging efficiency. Developers should choose the appropriate method based on project needs and ensure correct Log4j configuration to fully leverage CXF's logging capabilities.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.