Logging in mule is supported by SLF4J api . The default configuration can be found at $MULE_HOME/conf/log4j.properties . Application can be configured to have their own custom logging by having its own log4.properties in the app classpath . Here is the example log4j.properties file with rolling file appender . The logs will be created in $MULE_HOME/logs directory.
# Default log level
#log4j.rootCategory=INFO, console
log4j.rootCategory=DEBUG, console ,file
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%-5p %d [%t] %c: %m%n
################################################
# Rolling File Appender
################################################
log4j.appender.file=org.apache.log4j.RollingFileAppender
# Path and file name to store the log file.
log4j.appender.file.File=${mule.home}/logs/mule-logging-example.log
log4j.appender.file.MaxFileSize=15000KB
# Keep one backup file
log4j.appender.file.MaxBackupIndex=1
# Rolling File Appender layout
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d - %c - %p - %m%n
# CXF is used heavily by Mule for web services
log4j.logger.org.apache.cxf=WARN
# Apache Commons tend to make a lot of noise which can clutter the log.
log4j.logger.org.apache=WARN
# Reduce startup noise
log4j.logger.org.springframework.beans.factory=WARN
# Mule classes
log4j.logger.org.mule=INFO
This post describes how to create web service using mule .
Now to log request and response of rest service , we create a custom interceptor like this :
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mule.api.MuleEvent;
import org.mule.api.MuleException;
import org.mule.interceptor.AbstractEnvelopeInterceptor;
import org.mule.management.stats.ProcessingTime;
/**
*
*
* @author Abhishek Somani
*
*/
public class LoggingInterceptor extends AbstractEnvelopeInterceptor{
private static Log logger = LogFactory.getLog(LoggingInterceptor.class);
@Override
public MuleEvent before(MuleEvent event) throws MuleException {
try {
logger.debug("before call + " + event.getMessage().getPayloadAsString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return event;
}
@Override
public MuleEvent after(MuleEvent event) throws MuleException {
try {
logger.debug("after call + " + event.getMessage().getPayloadAsString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return event;
}
@Override
public MuleEvent last(MuleEvent event, ProcessingTime time, long startTime,
boolean exceptionWasThrown) throws MuleException {
logger.debug("process time " + time);
return event;
}
}
Now give the reference of this custom interceptor from your mule studio like this :
You might get following xml parsing error :
org.xml.sax.SAXParseException; lineNumber: 23; columnNumber: 62; cvc-complex-type.2.4.a: Invalid content was found starting with element 'custom-interceptor'. One of '{"http://www.mulesoft.org/schema/mule/core":abstract-component, "http://www.mulesoft.org/schema/mule/jersey":exception-mapper, "http://www.mulesoft.org/schema/mule/jersey":context-resolver}' is expected.
at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at org.apache.xerces.util.ErrorHandlerWrapper.error(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.reportSchemaError(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.handleStartElement(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.emptyElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:75)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:388)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:174)
at org.mule.config.spring.MuleApplicationContext.loadBeanDefinitions(MuleApplicationContext.java:112)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:131)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:522)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:436)
at org.mule.config.spring.SpringRegistry.doInitialise(SpringRegistry.java:89)
at org.mule.registry.AbstractRegistry.initialise(AbstractRegistry.java:109)
at org.mule.config.spring.SpringXmlConfigurationBuilder.createSpringRegistry(SpringXmlConfigurationBuilder.java:116)
at org.mule.config.spring.SpringXmlConfigurationBuilder.doConfigure(SpringXmlConfigurationBuilder.java:73)
at org.mule.config.builders.AbstractConfigurationBuilder.configure(AbstractConfigurationBuilder.java:46)
at org.mule.config.builders.AbstractResourceConfigurationBuilder.configure(AbstractResourceConfigurationBuilder.java:78)
at org.mule.config.builders.AutoConfigurationBuilder.autoConfigure(AutoConfigurationBuilder.java:101)
at org.mule.config.builders.AutoConfigurationBuilder.doConfigure(AutoConfigurationBuilder.java:57)
at org.mule.config.builders.AbstractConfigurationBuilder.configure(AbstractConfigurationBuilder.java:46)
at org.mule.config.builders.AbstractResourceConfigurationBuilder.configure(AbstractResourceConfigurationBuilder.java:78)
at org.mule.context.DefaultMuleContextFactory.createMuleContext(DefaultMuleContextFactory.java:80)
at org.mule.module.launcher.application.DefaultMuleApplication.init(DefaultMuleApplication.java:209)
at org.mule.module.launcher.application.ApplicationWrapper.init(ApplicationWrapper.java:64)
at org.mule.module.launcher.DefaultMuleDeployer.deploy(DefaultMuleDeployer.java:46)
at org.mule.tooling.server.application.ApplicationDeployer.run(ApplicationDeployer.java:56)
at org.mule.tooling.server.application.ApplicationDeployer.main(ApplicationDeployer.java:88)
Open your flow file in xml , and just change the order of your interceptor element . It should come just after jersey-component element .
Here is our flow xml file .
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:core="http://www.mulesoft.org/schema/mule/core"
xmlns:jersey="http://www.mulesoft.org/schema/mule/jersey"
xmlns:https="http://www.mulesoft.org/schema/mule/https"
xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"
version="EE-3.3.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/https http://www.mulesoft.org/schema/mule/https/current/mule-https.xsd
http://www.mulesoft.org/schema/mule/jersey http://www.mulesoft.org/schema/mule/jersey/current/mule-jersey.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd ">
<https:connector name="httpsConnector" doc:name="HTTP\HTTPS">
<https:tls-key-store path="keystore.jks" keyPassword="changeit" storePassword="changeit"/>
</https:connector>
<flow name="httpsRestServiceExampleFlow1" doc:name="httpsRestServiceExampleFlow1">
<https:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8082" connector-ref="httpsConnector" doc:name="HTTP"/>
<jersey:resources doc:name="REST">
<custom-interceptor class="LoggingInterceptor"/>
<component class="RestService"/>
</jersey:resources>
</flow>
</mule>
You can
Download Source here
So , by using interceptors , we can write debug logging information without modifying the code of our Rest web services .
Post Comments and Suggestions !!!