Tuesday, 27 August 2013

Textual description of firstImageUrl

Custom Interceptors And Logging in Mule ESB

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 !!!