Logging camel exceptions and sending to the dead letter channel
Asked Answered
B

2

10

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.

Barilla answered 4/12, 2012 at 20:39 Comment(0)
T
6

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?

Taxis answered 5/12, 2012 at 8:14 Comment(2)
Thanks for the reply. I thought there would be a simple workaround. I need to get my head into Camel-mode-of-thinking! Do I need to add something to the log step to get it to output the exception or does the mere presence of a log step mean that any exception on the exchange will be thrown out into the log file? We're using 2.10.2.Barilla
About the log then there is 2 different. Read the Camel docs at: camel.apache.org/log and camel.apache.org/logeip.htmlTaxis
W
7

Here is another option to log an exception and send exchange to dead letter queue, expressed in Camel DSL

Processor exceptionLoggingProcessor = (exchange) -> 
      logger.error("Error handled in camel.", exchange.getProperty(Exchange.EXCEPTION_CAUGHT));

setErrorHandlerBuilder(deadLetterChannel("direct:dlq")
    .onExceptionOccurred(exceptionLoggingProcessor));
Woof answered 6/7, 2016 at 14:35 Comment(0)
T
6

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?

Taxis answered 5/12, 2012 at 8:14 Comment(2)
Thanks for the reply. I thought there would be a simple workaround. I need to get my head into Camel-mode-of-thinking! Do I need to add something to the log step to get it to output the exception or does the mere presence of a log step mean that any exception on the exchange will be thrown out into the log file? We're using 2.10.2.Barilla
About the log then there is 2 different. Read the Camel docs at: camel.apache.org/log and camel.apache.org/logeip.htmlTaxis

© 2022 - 2024 — McMap. All rights reserved.