Since CXF 3.1 the message logging code was moved into a separate module and gathered some new features.
- Auto logging for existing CXF endpoints
- Uses slf4j MDC to log meta data separately
- Adds meta data for Rest calls
- Adds MD5 message id and exchange id for correlation
- Simple interface for writing your own appenders
Manual Usage
<jaxws:endpoint ...> <jaxws:features> <bean class="org.apache.cxf.ext.logging.LoggingFeature"/> </jaxws:features> </jaxws:endpoint>
The LoggingFeature can also be used with JAXRS Endpoints and can also be specified using the @Features annoation.
Auto logging for existing CXF endpoints in Apache Karaf
To use the message logging in karaf it needs to be installed as a feature. It can then be activated for all endpoints using a config.
feature:repo-add cxf 3.1.0 feature:install cxf-features-logging config:property-set -p org.apache.cxf.features.logging enabled true
Any CXF endpoints installed after the logging feature will automatically be enhanced with the message logging feature.
By default then all SOAP and Rest calls will be logged using slf4j. So the logging data will be processed by pax logging and by default end up in your karaf log.A log entry looks like this:
2015-06-08 16:35:54,068 | INFO | qtp1189348109-73 | REQ_IN | 90 - org.apache.cxf.cxf-rt-features-logging - 3.1.0 | <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:addPerson xmlns:ns2="http://model.personservice.cxf.karaf.tutorial.lr.net/" xmlns:ns3="http://person.jms2rest.camel.karaf.tutorial.lr.net"><arg0><id>3</id><name>Test2</name><url></url></arg0></ns2:addPerson></soap:Body></soap:Envelope>
This does not look very informative. You only see that it is an incoming request (REQ_IN) and the SOAP message in the log message. The logging feature provides a lot more information though. To leverage these the pax logging config can be changed to show the relevant MDC values.
Slf4j MDC values for meta data
This is the raw logging information you get for a SOAP call:
Field | Value |
---|---|
@timestamp | 2015-06-08T14:43:27,097Z |
MDC.address | http://localhost:8181/cxf/personService |
MDC.bundle.id | 90 |
MDC.bundle.name | org.apache.cxf.cxf-rt-features-logging |
MDC.bundle.version | 3.1.0 |
MDC.content-type | text/xml; charset=UTF-8 |
MDC.encoding | UTF-8 |
MDC.exchangeId | 56b037e3-d254-4fe5-8723-f442835fa128 |
MDC.headers | {content-type=text/xml; charset=UTF-8, connection=keep-alive, Host=localhost:8181, Content-Length=251, SOAPAction="", User-Agent=Apache CXF 3.1.0, Accept=*/*, Pragma=no-cache, Cache-Control=no-cache} |
MDC.httpMethod | POST |
MDC.messageId | a46eebd2-60af-4975-ba42-8b8205ac884c |
MDC.portName | PersonServiceImplPort |
MDC.portTypeName | PersonService |
MDC.serviceName | PersonServiceImplService |
MDC.type | REQ_IN |
level | INFO |
loc.class | org.apache.cxf.ext.logging.slf4j.Slf4jEventSender |
loc.file | Slf4jEventSender.java |
loc.line | 55 |
loc.method | send |
loggerClass | org.ops4j.pax.logging.slf4j.Slf4jLogger |
loggerName | org.apache.cxf.services.PersonService.REQ_IN |
message | <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getAll xmlns:ns2="http://model.personservice.cxf.karaf.tutorial.lr.net/"; xmlns:ns3="http://person.jms2rest.camel.karaf.tutorial.lr.net"/></soap:Body></soap:Envelope>; |
threadName | qtp80604361-78 |
timeStamp | 1433774607097 |
Some things to note:
- The logger name is <service namespace>.<ServiceName>.<type> karaf by default only cuts it to just the type.
- A lot of the details are in the MDC values
You need to change your pax logging config to make these visible.
You can use the logger name to fine tune which services you want to log this way. For example set the debug level to WARN for noisy services to avoid that they are logged or log some services to another file.
Message id and exchange id
The messageId allows to uniquely identify messages even if they were collected from several servers. It is also transported over the wire so a request sent on one machine can be correlated with the request received on another machine.
The exchangeId will be the same for an incoming request and the response sent out or on the other side for an outgoing request and the response for it. This allows to correlate request and responses and so follow the conversations.
Simple interface to write custom appenders
Write a custom LogSender and set it on the LoggingFeature to do custom logging. All meta data can be access from the class LogEvent.