Logging camel exceptions and sending to the dead letter channel

Jeremy Gooch picture Jeremy Gooch · Dec 4, 2012 · Viewed 13.7k times · Source

I have a Camel route, running within Karaf, for which I've added a Dead Letter Channel. This is to handle cases where the route fails and I want to keep the problem message and log the cause. I can't throw the exception back to the calling application as I'm handling some processing asynchronously.

From reading the documentation and trying a number of cases, it's not clear to me how to both log the exception into Karaf's log and deposit the original message onto the dead letter queue.

Here's an excerpt of what I've got:-

<bean id="deadLetterQueue" class="org.apache.camel.builder.DeadLetterChannelBuilder">
    <property name="deadLetterUri" value="activemq:dead.letter.queue"/>
    <property name="redeliveryPolicy" ref="redeliveryPolicy"/>
</bean>

<bean id="redeliveryPolicy" class="org.apache.camel.processor.RedeliveryPolicy">
    <property name="maximumRedeliveries" value="1"/>
    <property name="redeliveryDelay" value="1000"/>
</bean>

<camelContext id="notification" errorHandlerRef="deadLetterQueue"
    trace="false" xmlns="http://camel.apache.org/schema/blueprint">
    <onException>
        <exception>org.xyz.exceptions.unchecked.notificationException</exception>
        <log logName="notifications" loggingLevel="ERROR"
            message="Exception from notification Camel route" />
    </onException>

    <route id="DoSomething" errorHandlerRef="deadLetterQueue">
        <from uri="activemq:notification.in" />
        <log logName="notifications" loggingLevel="TRACE"
            message="Notification route initiated" />
        <bean ref="NotificationProcessor" method="doStuff" />
    </route>
</camelContext>

If I remove the "onException" structure then, in all exception cases, the source message appears on the dead letter queue but isn't logged.

If I run it as above then the exception trace is logged into Karaf's log (if it is a "notificationException") but the associated source message is not rolled back to the dead letter queue and disappears into the ether (presumably as it thinks I've handled it within the "onException" structure).

Having looked at the different sorts of error handlers, I tried instead adding things to the DeadLetterChannelBuilder such as...

<property name="logName" value="notifications"/>
<property name="level" value="ERROR"/>

...but these aren't legal properties.

It also strikes me that having to list the different exceptions explicitly in the onException clause can't be correct.

So, how do I get the dead letter channel to log the exception trace as well as putting the message onto the queue? Perhaps the dead letter channel isn't the correct handler - I'm not really interested in automatic redelivery in this case.

Thanks for any guidance,

J.

Answer

Claus Ibsen picture Claus Ibsen · Dec 5, 2012

You can just use a route for the dead letter queue, and do logging and sending to JMS queue. And then use direct to refer to this route

<property name="deadLetterUri" value="direct:myDLC"/>

<route>
  <from uri="direct:myDLC"/>
  <log logName="notifications" loggingLevel="ERROR"
            message="Exception from notification Camel route" />
  <to uri="activemq:dead.letter.queue"/>
</route>

What version of Camel are you using?