In the post I will describe how to configure Fuse ESB to
automatically send emails when certain logging events occur. This technique
uses Log4j’s SMTPAppender.
Log4j can be configured to push email notification
immediately when an ERROR occurs inside the ESB.
The configuration of the SMTPAppender within Fuse is not
particularly straight forward. There are some gotchas that I have attempted to
point out here. Perhaps future versions of Fuse will make it easier to
configure this.
These instructions are written based on Fuse version
6.0.0.redhat-024 available for download in platform independent form here
(download zip file):
h
ttp://repo.fusesource.com/nexus/content/groups/public/org/jboss/fuse/jboss-fuse/6.0.0.redhat-024/
Or, assuming you have maven installed, the following command
will download the installation .zip file, and put the file into your local
maven repository:
mvn
org.apache.maven.plugins:maven-dependency-plugin:2.8:get
-Dartifact=org.jboss.fuse:jboss-fuse:6.0.0.redhat-024:zip
Some of the complications with getting this to work are reported
in the following bug report:
https://issues.apache.org/jira/i#browse/KARAF-3067
My research indicates that you must apply the configuration
to a “fresh” installation of Fuse. If you have an existing installation of
Fuse, you must clear the bundle cache (i.e. completely remove the ‘data’
directory), then make the necessary configuration changes before starting Fuse
for the first time. This is annoying if you have an existing installation and
merely wish to add the feature to an existing installation.
Here are the steps I took to enable SMTPAppender on a fresh
install of Fuse. Before starting Fuse for the first time, I applied the
following steps:
1)
Added configuration for the SMTP Appender (as shown
below) into [jboss-fuse-6.0]/etc /org.ops4j.pax.logging.cfg. Be sure to back up
the file first. See updated configuration below:
#
Root logger
log4j.rootLogger=INFO,
out, osgi:VmLogAppender, mail
…
…
#
SMTP appender
log4j.appender.mail=org.apache.log4j.net.SMTPAppender
log4j.appender.mail.layout=org.apache.log4j.PatternLayout
log4j.appender.mail.layout.ConversionPattern=%d
[%t] %-5p %c %x - %m%n
log4j.appender.mail.SMTPPort=25
log4j.appender.mail.SMTPProtocol=smtp
log4j.appender.mail.Subject=JBoss
Fuse 6.0 Error Log Message
log4j.appender.mail.SendOnClose=false
log4j.appender.mail.SMTPHost
= mailrelay.mycompany.com
log4j.appender.mail.From=username@host1.mycompany.com
log4j.appender.mail.To=lcurry@mycompany.com
#log4j.appender.mail.Threshold=INFO
log4j.appender.mail.SMTPDebug=true
#log4j.appender.mail.SMTPPassword=********
#log4j.appender.mail.SMTPUsername=user@gmail.com
log4j.appender.mail.BufferSize=512
2)
In the [jboss-fuse-6.0]/etc/jre.properties file I needed
to comment out the javax.activation;version="1.1".
This ‘jre.properties’ file allow
you to define in Fuse ESB which packages should be provided by the JRE and
which can be provided by application bundles. To customize this you can tune
the ‘jre.properties’ file. So, you can update this file to prevent JRE’s
package ‘javax.activation’ from being exported.
Again make a backup of ‘jre.properties’
before modifying.
Now modify the file as indicated
below: Note there are two occurences of ‘javax.activation’ (for JRE 1.6 and
1.7) and you should comment out both.
#
Standard package set. Note that:
# - javax.transaction* is exported with a mandatory
attribute
jre-1.6=
\
javax.accessibility, \
#
javax.activation;version="1.1", \
javax.activity, \
javax.annotation;version="1.1", \
javax.annotation.processing;version="1.1",
\
javax.crypto, \
javax.crypto.interfaces, \
javax.crypto.spec, \
…
…
#
Standard package set. Note that:
# - javax.transaction* is exported with a
mandatory attribute
jre-1.7=
\
javax.accessibility, \
#
javax.activation;version="1.1", \
javax.activity, \
javax.annotation;version="1.1", \
javax.annotation.processing;version="1.1",
\
javax.crypto, \
javax.crypto.interfaces, \
javax.crypto.spec, \
javax.imageio, \
3)
Because (previous step) will block the JRE’s
version of the package ‘javax.activation’ from being exported, we can force a
different version of this package to be used by Fuse. To do this, copy the following JAR to
[jboss-fuse-6.0]/lib/endorsed
org.apache.servicemix.specs.activation-api-1.1-2.0.0.redhat-60024.jar
You can retrieve the JAR file from the following public
maven repository:
http://repo.fusesource.com/nexus/content/groups/public/org/apache/servicemix/specs/org.apache.servicemix.specs.activation-api-1.1/2.0.0.redhat-60024/
Or, assuming you have maven installed, the following command
will download the JAR file into your local maven repository:
mvn
org.apache.maven.plugins:maven-dependency-plugin:2.8:get
-Dartifact=org.apache.servicemix.specs:org.apache.servicemix.specs.activation-api-1.1:2.0.0.redhat-60024
Note: The
org.apache.servicemix.specs.activator-2.0.0.redhat-60024.jar should be in the
[jboss-fuse-6.0]/lib directory, and should already be there by default.
4)
The Log4J SMTPAppender requires a mail bundle be
deployed into Fuse. Therefore we must add a mail bundle to Fuse. The
recommended way to do this is to configure Fuse so that the bundle is deployed
on start-up. Define your own custom feature with a start level low enough to
take precendence. I picked up this trick up from KARAF-3067. This ensure supported version of javax.mail
API is installed and used.
I created a feature called
‘javax.mail’. The feature descriptor is
called ‘javax.mail-1.0.0.redhat-60024-features.xml.’
<features>
<feature name="javax.mail"
version="1.4.5">
<bundle
start-level="7">mvn:javax.mail/mail/1.4.5</bundle>
</feature>
</features>
Copy above feature descriptor to a location where Fuse can
find it. Create a directory ‘local-repo’ in the root installation folder. Fuse
will look there by default for maven dependencies. The complete path to the
location where I copied the descriptor was as follows: [jboss-fuse-6.0]/
local-repo/com/mycompany/features/javax.mail/1.0.0.redhat-60024
The name of the feature descriptor file in that directory
was:
javax.mail-1.0.0.redhat-60024-features.xml
Remember, the actual name of the feature descriptor file and
the location where it is copied matter (a lot). The location must match the
standard well-known maven directory location based on
groupId/artifactId/version coordinates.
5)
Add the custom feature ‘javax.mail’ to the set
of features that Fuse installs at startup.
So once I have the feature
descriptor file in the correct location where Fuse can find it, I will add the
feature to the list of features that get installed at Fuse startup. To do this
add the feature to the file ‘[jboss-fuse-6.0]/etc/org.apache.karaf.features.cfg’
. Make a backup of this file, and below
shows the necessary additions to this file.
#
# Comma separated list of
features repositories to register by default
#
featuresRepositories=\
mvn:org.apache.karaf.assemblies.features/standard/2.3.0.redhat-60024/xml/features,\
mvn:org.apache.karaf.assemblies.features/enterprise/2.3.0.redhat-60024/xml/features,\
mvn:org.apache.cxf.karaf/apache-cxf/2.6.0.redhat-60024/xml/features,\
mvn:org.apache.camel.karaf/apache-camel/2.10.0.redhat-60024/xml/features,\
mvn:org.apache.activemq/activemq-karaf/5.8.0.redhat-60024/xml/features,\
mvn:org.apache.servicemix.nmr/apache-servicemix-nmr/1.6.0.redhat-60024/xml/features,\
mvn:org.fusesource.fabric/fuse-fabric/7.2.0.redhat-024/xml/features,\
mvn:org.jboss.fuse/jboss-fuse/6.0.0.redhat-024/xml/features,\
mvn:org.fusesource.patch/patch-features/7.2.0.redhat-024/xml/features,\
mvn:com.mycompany.features/javax.mail/1.0.0.redhat-60024/xml/features
#
# Comma separated list of
features to install at startup
#
featuresBoot=javax.mail,jasypt-encryption,config,management,fabric-boot-commands,fabric-bundle,fabric-maven-proxy,patch,activemq,mq-fabric,camel,camel-cxf,camel-jms,activemq-camel,camel-blueprint,camel-csv,camel-ftp,camel-bindy,camel-jdbc,camel-exec,camel-jasypt,camel-saxon,camel-snmp,camel-ognl,camel-routebox,camel-script,camel-spring-javaconfig,camel-jaxb,camel-jetty,camel-jmx,camel-mail,camel-paxlogging,camel-rmi,war
Note the addition of the feature URL in the
‘featuresRepositories’ property and also the additional feature ‘javax.mail’
added to the front of the ‘featuresBoot’ list.
6)
Finally, after configuring everything - I start Fuse. The first time I start Fuse
after making the configuration changes described above, I got an ERROR that
looked something like this:
14:25:46,185 | ERROR |
s4j.pax.logging) | configadmin | 5 -
org.apache.felix.configadm
in - 1.4.0.redhat-60024 |
[org.osgi.service.log.LogService, org.knopflerfish.service.log.LogService,
org.op
s4j.pax.logging.PaxLoggingService,
org.osgi.service.cm.ManagedService, id=9, bundle=3/mvn:org.ops4j.pax.log
ging/pax-logging-service/1.7.0]:
Unexpected problem updating configuration org.ops4j.pax.logging
java.lang.NoClassDefFoundError:
javax/mail/MessagingException
at
java.lang.Class.getDeclaredConstructors0(Native Method)
at
java.lang.Class.privateGetDeclaredConstructors(Class.java:2532)
at java.lang.Class.getConstructor0(Class.java:2842)
at
java.lang.Class.newInstance(Class.java:345)
at
org.apache.log4j.helpers.OptionConverter.instantiateByClassName(OptionConverter.java:336)
at
org.apache.log4j.helpers.OptionConverter.instantiateByKey(OptionConverter.java:123)
at
org.apache.log4j.PaxLoggingConfigurator.parseAppender(PaxLoggingConfigurator.java:97)
at
org.apache.log4j.PropertyConfigurator.parseCategory(PropertyConfigurator.java:735)
at org.apache.log4j.PropertyConfigurator.configureRootCategory(PropertyConfigurator.java:615)
at
org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:502)
at
org.apache.log4j.PaxLoggingConfigurator.doConfigure(PaxLoggingConfigurator.java:72)
at
org.ops4j.pax.logging.service.internal.PaxLoggingServiceImpl.updated PaxLoggingServiceImpl.java:
214)
I had to shut down and restart Fuse. The second start seemed
to do the trick. At that point I can see the debug logging for SMTP (only from
the Fuse console.) If the container is properly configured, and when you start
Fuse (the second time) you will see some logging at the Fuse console that
indicates the SMTPAppender is operational (per setting log4j.appender.mail.SMTPDebug=true):
Note: I only saw debug output for log4j SMTP (based on log4j.appender.mail.SMTPDebug=true) only if I
started Fuse in foreground using './fuse' rather than starting Fuse in
background with './start'.
7)
To test the email notification, deliberately cause
an error in Fuse. For example, you could bogus spring file into the deploy
directory (purposely include invalid XML so that the ESB gets an ERROR.) You should see debug in the Fuse console
indicating an email being sent. Or you may see an error of some sort indicating
further configuration required for SMTP to work properly.