Author: davsclaus Date: Sat Feb 27 10:47:58 2010 New Revision: 916940 URL: http://svn.apache.org/viewvc?rev=916940&view=rev Log: CAMEL-2504: Handled exceptions is not logged by default. Added more options to easily enable/disable logging behavior with error handling.
Added: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RedeliveryErrorHandlerLogHandledTest.java (with props) Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java camel/trunk/camel-core/src/main/java/org/apache/camel/model/OnExceptionDefinition.java camel/trunk/camel-core/src/main/java/org/apache/camel/model/RedeliveryPolicyDefinition.java camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryPolicy.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java?rev=916940&r1=916939&r2=916940&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java Sat Feb 27 10:47:58 2010 @@ -131,6 +131,16 @@ return this; } + public DefaultErrorHandlerBuilder logHandled(boolean logHandled) { + getRedeliveryPolicy().setLogHandled(logHandled); + return this; + } + + public DefaultErrorHandlerBuilder logExhausted(boolean logExhausted) { + getRedeliveryPolicy().setLogExhausted(logExhausted); + return this; + } + /** * Sets whether the exchange should be marked as handled or not. * Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/OnExceptionDefinition.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/OnExceptionDefinition.java?rev=916940&r1=916939&r2=916940&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/model/OnExceptionDefinition.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/OnExceptionDefinition.java Sat Feb 27 10:47:58 2010 @@ -331,6 +331,46 @@ } /** + * Sets whether to log stacktrace for failed messages. + */ + public OnExceptionDefinition logStackTrace(boolean logStackTrace) { + getOrCreateRedeliveryPolicy().setLogStackTrace(logStackTrace); + return this; + } + + /** + * Sets whether to log stacktrace for failed redelivery attempts + */ + public OnExceptionDefinition logRetryStackTrace(boolean logRetryStackTrace) { + getOrCreateRedeliveryPolicy().setLogRetryStackTrace(logRetryStackTrace); + return this; + } + + /** + * Sets whether to log errors even if its handled + */ + public OnExceptionDefinition logHandled(boolean logHandled) { + getOrCreateRedeliveryPolicy().setLogHandled(logHandled); + return this; + } + + /** + * Sets whether to log retry attempts + */ + public OnExceptionDefinition logRetryAttempted(boolean logRetryAttempted) { + getOrCreateRedeliveryPolicy().setLogRetryAttempted(logRetryAttempted); + return this; + } + + /** + * Sets whether to log exhausted exceptions + */ + public OnExceptionDefinition logExhausted(boolean logExhausted) { + getOrCreateRedeliveryPolicy().setLogExhasted(logExhausted); + return this; + } + + /** * Sets the maximum redeliveries * <ul> * <li>5 = default value</li> Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/RedeliveryPolicyDefinition.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/RedeliveryPolicyDefinition.java?rev=916940&r1=916939&r2=916940&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/model/RedeliveryPolicyDefinition.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/RedeliveryPolicyDefinition.java Sat Feb 27 10:47:58 2010 @@ -55,8 +55,16 @@ @XmlAttribute private LoggingLevel retryAttemptedLogLevel; @XmlAttribute + private Boolean logRetryAttempted; + @XmlAttribute private Boolean logStackTrace; @XmlAttribute + private Boolean logRetryStackTrace; + @XmlAttribute + private Boolean logHandled; + @XmlAttribute + private Boolean logExhasted; + @XmlAttribute private Boolean disableRedelivery; public RedeliveryPolicy createRedeliveryPolicy(CamelContext context, RedeliveryPolicy parentPolicy) { @@ -98,6 +106,18 @@ if (logStackTrace != null) { answer.setLogStackTrace(logStackTrace); } + if (logRetryStackTrace != null) { + answer.setLogRetryStackTrace(logRetryStackTrace); + } + if (logHandled != null) { + answer.setLogHandled(logHandled); + } + if (logRetryAttempted != null) { + answer.setLogRetryAttempted(logRetryAttempted); + } + if (logExhasted != null) { + answer.setLogExhausted(logExhasted); + } if (disableRedelivery != null && disableRedelivery) { answer.setMaximumRedeliveries(0); } @@ -178,9 +198,10 @@ } /** - * Sets wheter stack traces should be logged, can be used to reduce verbose. + * Sets whether stack traces should be logged. + * Can be used to include or reduce verbose. * - * @param logStackTrace wheter stack traces should be logged or not + * @param logStackTrace whether stack traces should be logged or not * @return the builder */ public RedeliveryPolicyDefinition logStackTrace(boolean logStackTrace) { @@ -188,8 +209,54 @@ return this; } + /** + * Sets whether stack traces should be logged when an retry attempt failed. + * Can be used to include or reduce verbose. + * + * @param logRetryStackTrace whether stack traces should be logged or not + * @return the builder + */ + public RedeliveryPolicyDefinition logRetryStackTrace(boolean logRetryStackTrace) { + setLogRetryStackTrace(logRetryStackTrace); + return this; + } + + /** + * Sets whether retry attempts should be logged or not + * Can be used to include or reduce verbose. + * + * @param logRetryAttempted whether retry attempts should be logged or not + * @return the builder + */ + public RedeliveryPolicyDefinition logRetryAttempted(boolean logRetryAttempted) { + setLogRetryAttempted(logRetryAttempted); + return this; + } + + /** + * Sets whether handled exceptions should be logged or not + * Can be used to include or reduce verbose. + * + * @param logHandled whether handled exceptions should be logged or not + * @return the builder + */ + public RedeliveryPolicyDefinition logHandled(boolean logHandled) { + setLogHandled(logHandled); + return this; + } + + /** + * Sets whether exhausted exceptions should be logged or not + * Can be used to include or reduce verbose. + * + * @param logExhausted whether exhausted exceptions should be logged or not + * @return the builder + */ + public RedeliveryPolicyDefinition logExhausted(boolean logExhausted) { + setLogExhasted(logExhausted); + return this; + } - /** * Sets the maximum redeliveries * <ul> @@ -346,4 +413,36 @@ public void setDisableRedelivery(Boolean disableRedelivery) { this.disableRedelivery = disableRedelivery; } + + public Boolean isLogRetryStackTrace() { + return logRetryStackTrace; + } + + public void setLogRetryStackTrace(Boolean logRetryStackTrace) { + this.logRetryStackTrace = logRetryStackTrace; + } + + public Boolean isLogHandled() { + return logHandled; + } + + public void setLogHandled(Boolean logHandled) { + this.logHandled = logHandled; + } + + public Boolean isLogRetryAttempted() { + return logRetryAttempted; + } + + public void setLogRetryAttempted(Boolean logRetryAttempted) { + this.logRetryAttempted = logRetryAttempted; + } + + public Boolean isLogExhasted() { + return logExhasted; + } + + public void setLogExhasted(Boolean logExhasted) { + this.logExhasted = logExhasted; + } } Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java?rev=916940&r1=916939&r2=916940&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java Sat Feb 27 10:47:58 2010 @@ -261,7 +261,7 @@ String msg = "Failed delivery for exchangeId: " + exchange.getExchangeId() + ". On delivery attempt: " + data.redeliveryCounter + " caught: " + e; - logFailedDelivery(true, exchange, msg, data, e); + logFailedDelivery(true, false, exchange, msg, data, e); data.redeliveryCounter = incrementRedeliveryCounter(exchange, e); } @@ -300,10 +300,12 @@ // clear exception as we let the failure processor handle it exchange.setException(null); + boolean handled = false; if (data.handledPredicate != null && data.handledPredicate.matches(exchange)) { // its handled then remove traces of redelivery attempted exchange.getIn().removeHeader(Exchange.REDELIVERED); exchange.getIn().removeHeader(Exchange.REDELIVERY_COUNTER); + handled = true; } else { // must decrement the redelivery counter as we didn't process the redelivery but is // handling by the failure handler. So we must -1 to not let the counter be out-of-sync @@ -345,7 +347,7 @@ } // log that we failed delivery as we are exhausted - logFailedDelivery(false, exchange, msg, data, null); + logFailedDelivery(false, handled, exchange, msg, data, null); } protected void prepareExchangeAfterFailure(final Exchange exchange, final RedeliveryData data) { @@ -389,11 +391,26 @@ } } - private void logFailedDelivery(boolean shouldRedeliver, Exchange exchange, String message, RedeliveryData data, Throwable e) { + private void logFailedDelivery(boolean shouldRedeliver, boolean handled, Exchange exchange, String message, RedeliveryData data, Throwable e) { if (logger == null) { return; } + if (handled && !data.currentRedeliveryPolicy.isLogHandled()) { + // do not log handled + return; + } + + if (shouldRedeliver && !data.currentRedeliveryPolicy.isLogRetryAttempted()) { + // do not log retry attempts + return; + } + + if (!shouldRedeliver && !data.currentRedeliveryPolicy.isLogExhausted()) { + // do not log exhausted + return; + } + LoggingLevel newLogLevel; boolean logStrackTrace; if (shouldRedeliver) { Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryPolicy.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryPolicy.java?rev=916940&r1=916939&r2=916940&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryPolicy.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RedeliveryPolicy.java Sat Feb 27 10:47:58 2010 @@ -45,8 +45,11 @@ * <li>useCollisionAvoidance = false</li> * <li>retriesExhaustedLogLevel = LoggingLevel.ERROR</li> * <li>retryAttemptedLogLevel = LoggingLevel.DEBUG</li> + * <li>logRetryAttempted = true</li> * <li>logRetryStackTrace = false</li> * <li>logStackTrace = true</li> + * <li>logHandled = false</li> + * <li>logExhausted = true</li> * </ul> * <p/> * Setting the maximumRedeliveries to a negative value such as -1 will then always redeliver (unlimited). @@ -88,6 +91,9 @@ protected LoggingLevel retryAttemptedLogLevel = LoggingLevel.DEBUG; protected boolean logStackTrace = true; protected boolean logRetryStackTrace; + protected boolean logHandled; + protected boolean logExhausted = true; + protected boolean logRetryAttempted = true; protected String delayPattern; public RedeliveryPolicy() { @@ -100,8 +106,11 @@ + ", maximumRedeliveryDelay=" + maximumRedeliveryDelay + ", retriesExhaustedLogLevel=" + retriesExhaustedLogLevel + ", retryAttemptedLogLevel=" + retryAttemptedLogLevel + + ", logRetryAttempted=" + logRetryAttempted + ", logStackTrace=" + logStackTrace + ", logRetryStackTrace=" + logRetryStackTrace + + ", logHandled=" + logHandled + + ", logExhausted=" + logExhausted + ", useExponentialBackOff=" + useExponentialBackOff + ", backOffMultiplier=" + backOffMultiplier + ", useCollisionAvoidance=" + useCollisionAvoidance @@ -296,10 +305,18 @@ public RedeliveryPolicy retryAttemptedLogLevel(LoggingLevel retryAttemptedLogLevel) { setRetryAttemptedLogLevel(retryAttemptedLogLevel); return this; - } - + } + + /** + * Sets whether to log retry attempts + */ + public RedeliveryPolicy logRetryAttempted(boolean logRetryAttempted) { + setLogRetryAttempted(logRetryAttempted); + return this; + } + /** - * Sets whether to log stacktraces for failed messages. + * Sets whether to log stacktrace for failed messages. */ public RedeliveryPolicy logStackTrace(boolean logStackTrace) { setLogStackTrace(logStackTrace); @@ -315,6 +332,22 @@ } /** + * Sets whether to log errors even if its handled + */ + public RedeliveryPolicy logHandled(boolean logHandled) { + setLogHandled(logHandled); + return this; + } + + /** + * Sets whether to log exhausted errors + */ + public RedeliveryPolicy logExhausted(boolean logExhausted) { + setLogExhausted(logExhausted); + return this; + } + + /** * Sets the delay pattern with delay intervals. */ public RedeliveryPolicy delayPattern(String delayPattern) { @@ -494,4 +527,36 @@ this.logRetryStackTrace = logRetryStackTrace; } + public boolean isLogHandled() { + return logHandled; + } + + /** + * Sets whether errors should be logged even if its handled + */ + public void setLogHandled(boolean logHandled) { + this.logHandled = logHandled; + } + + public boolean isLogRetryAttempted() { + return logRetryAttempted; + } + + /** + * Sets whether retry attempts should be logged or not + */ + public void setLogRetryAttempted(boolean logRetryAttempted) { + this.logRetryAttempted = logRetryAttempted; + } + + public boolean isLogExhausted() { + return logExhausted; + } + + /** + * Sets whether exhausted exceptions should be logged or not + */ + public void setLogExhausted(boolean logExhausted) { + this.logExhausted = logExhausted; + } } Added: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RedeliveryErrorHandlerLogHandledTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RedeliveryErrorHandlerLogHandledTest.java?rev=916940&view=auto ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RedeliveryErrorHandlerLogHandledTest.java (added) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RedeliveryErrorHandlerLogHandledTest.java Sat Feb 27 10:47:58 2010 @@ -0,0 +1,211 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.processor; + +import org.apache.camel.CamelException; +import org.apache.camel.CamelExecutionException; +import org.apache.camel.ContextTestSupport; +import org.apache.camel.LoggingLevel; +import org.apache.camel.builder.RouteBuilder; + +/** + * @version $Revision$ + */ +public class RedeliveryErrorHandlerLogHandledTest extends ContextTestSupport { + + @Override + public boolean isUseRouteBuilder() { + return false; + } + + public void testRedeliveryErrorHandlerOnExceptionLogHandledDefault() throws Exception { + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + onException(IllegalArgumentException.class) + .maximumRedeliveries(3) + .handled(true) + .to("mock:handled"); + + from("direct:foo") + .throwException(new IllegalArgumentException("Damn")); + } + }); + context.start(); + + getMockEndpoint("mock:handled").expectedBodiesReceived("Hello World"); + + template.sendBody("direct:foo", "Hello World"); + + assertMockEndpointsSatisfied(); + } + + public void testRedeliveryErrorHandlerOnExceptionLogHandled() throws Exception { + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + onException(IllegalArgumentException.class) + .maximumRedeliveries(3) + .logHandled(true) + .handled(true) + .to("mock:handled"); + + from("direct:foo") + .throwException(new IllegalArgumentException("Damn")); + } + }); + context.start(); + + getMockEndpoint("mock:handled").expectedBodiesReceived("Hello World"); + + template.sendBody("direct:foo", "Hello World"); + + assertMockEndpointsSatisfied(); + } + + public void testRedeliveryErrorHandlerOnExceptionLogRetryAttempted() throws Exception { + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + onException(IllegalArgumentException.class) + .maximumRedeliveries(3) + .logHandled(true) + .logRetryAttempted(true) + .handled(true) + .to("mock:handled"); + + from("direct:foo") + .throwException(new IllegalArgumentException("Damn")); + } + }); + context.start(); + + getMockEndpoint("mock:handled").expectedBodiesReceived("Hello World"); + + template.sendBody("direct:foo", "Hello World"); + + assertMockEndpointsSatisfied(); + } + + public void testRedeliveryErrorHandlerDoNotLogExhausted() throws Exception { + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + errorHandler(defaultErrorHandler().logExhausted(false)); + + from("direct:bar") + .throwException(new CamelException("Camel rocks")); + } + }); + context.start(); + + getMockEndpoint("mock:handled").expectedMessageCount(0); + + try { + template.sendBody("direct:bar", "Hello World"); + fail("Should thrown an exception"); + } catch (CamelExecutionException e) { + CamelException cause = assertIsInstanceOf(CamelException.class, e.getCause()); + assertEquals("Camel rocks", cause.getMessage()); + } + + assertMockEndpointsSatisfied(); + } + + public void testRedeliveryErrorHandlerLogExhaustedDefault() throws Exception { + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + errorHandler(defaultErrorHandler()); + + from("direct:bar") + .throwException(new CamelException("Camel rocks")); + } + }); + context.start(); + + getMockEndpoint("mock:handled").expectedMessageCount(0); + + try { + template.sendBody("direct:bar", "Hello World"); + fail("Should thrown an exception"); + } catch (CamelExecutionException e) { + CamelException cause = assertIsInstanceOf(CamelException.class, e.getCause()); + assertEquals("Camel rocks", cause.getMessage()); + } + + assertMockEndpointsSatisfied(); + } + + public void testRedeliveryErrorHandlerAllOptions() throws Exception { + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + errorHandler(defaultErrorHandler() + .maximumRedeliveries(3) + .logExhausted(true).logHandled(true).logRetryStackTrace(true).logStackTrace(true) + .retryAttemptedLogLevel(LoggingLevel.WARN).retriesExhaustedLogLevel(LoggingLevel.ERROR)); + + from("direct:bar") + .throwException(new CamelException("Camel rocks")); + } + }); + context.start(); + + getMockEndpoint("mock:handled").expectedMessageCount(0); + + try { + template.sendBody("direct:bar", "Hello World"); + fail("Should thrown an exception"); + } catch (CamelExecutionException e) { + CamelException cause = assertIsInstanceOf(CamelException.class, e.getCause()); + assertEquals("Camel rocks", cause.getMessage()); + } + + assertMockEndpointsSatisfied(); + } + + public void testRedeliveryErrorHandlerOnExceptionAllOptions() throws Exception { + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + onException(IllegalArgumentException.class) + .maximumRedeliveries(3) + .logHandled(true) + .logRetryAttempted(true) + .logRetryStackTrace(true) + .logExhausted(true) + .logStackTrace(true) + .handled(true) + .retryAttemptedLogLevel(LoggingLevel.WARN) + .retriesExhaustedLogLevel(LoggingLevel.ERROR) + .to("mock:handled"); + + from("direct:foo") + .throwException(new IllegalArgumentException("Damn")); + } + }); + context.start(); + + getMockEndpoint("mock:handled").expectedBodiesReceived("Hello World"); + + template.sendBody("direct:foo", "Hello World"); + + assertMockEndpointsSatisfied(); + } + +} Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RedeliveryErrorHandlerLogHandledTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RedeliveryErrorHandlerLogHandledTest.java ------------------------------------------------------------------------------ svn:keywords = Rev Date