Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Logging camel exceptions and sending to the dead letter channel

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.

like image 785
Jeremy Gooch Avatar asked Dec 04 '12 20:12

Jeremy Gooch


People also ask

What is redelivery in Camel?

A redelivery policy defines rules when Camel Error Handler perform redelivery attempts. For example you can setup rules that state how many times to try redelivery, and the delay in between attempts, and so forth. You can use redelivery policies at two places in Camel: Error Handler. onException.

What is Uri in Apache Camel?

Camel makes extensive use of URIs to allow you to refer to Endpoints. This endpoint is created by the Kafka component. The URI contains endpoint configurations as context-path and query parameters.

What is Camel message?

camel. Message is the data record that represents the message part of the Exchange. The message contains the following information: body - the message body (i.e. payload) headers - headers with additional information.


2 Answers

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));
like image 115
Ioannis Sermetziadis Avatar answered Oct 08 '22 04:10

Ioannis Sermetziadis


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?

like image 33
Claus Ibsen Avatar answered Oct 08 '22 04:10

Claus Ibsen