GH-3555: Change logger order for errorChannel (#3949)
* GH-3555: Change logger order for errorChannel Fixes https://github.com/spring-projects/spring-integration/issues/3555 The default global `errorChannel` has a `LoggingHandler` as a subscriber. It is subscribed without any `order` which may lose logging messages, when another subscriber with re-throw is present. * Set default `LoggingHandler` on the default `errorChannel` to `Ordered.LOWEST_PRECEDENCE - 100` to give a room for custom subscribers without an `order` and still get error logged * Add extra note in docs about an order for custom subcribers Co-authored-by: Gary Russell <grussell@vmware.com> Co-authored-by: Gary Russell <grussell@vmware.com>
This commit is contained in:
@@ -36,12 +36,14 @@ import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
import org.springframework.integration.channel.ChannelUtils;
|
||||
import org.springframework.integration.channel.DefaultHeaderChannelRegistry;
|
||||
import org.springframework.integration.channel.MessagePublishingErrorHandler;
|
||||
import org.springframework.integration.channel.NullChannel;
|
||||
import org.springframework.integration.channel.PublishSubscribeChannel;
|
||||
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
|
||||
import org.springframework.integration.context.IntegrationContextUtils;
|
||||
import org.springframework.integration.context.IntegrationProperties;
|
||||
import org.springframework.integration.handler.LoggingHandler;
|
||||
@@ -221,6 +223,7 @@ public class DefaultConfiguringBeanFactoryPostProcessor
|
||||
BeanDefinitionBuilder.genericBeanDefinition(LoggingHandler.class,
|
||||
() -> new LoggingHandler(LoggingHandler.Level.ERROR))
|
||||
.addConstructorArgValue(LoggingHandler.Level.ERROR)
|
||||
.addPropertyValue(IntegrationNamespaceUtils.ORDER, Ordered.LOWEST_PRECEDENCE - 100)
|
||||
.getBeanDefinition());
|
||||
|
||||
BeanDefinitionBuilder loggingEndpointBuilder =
|
||||
|
||||
@@ -16,12 +16,17 @@
|
||||
|
||||
package org.springframework.integration.config.xml;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.integration.channel.PublishSubscribeChannel;
|
||||
import org.springframework.integration.handler.LoggingHandler;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -43,6 +48,15 @@ public class ErrorChannelAutoCreationTests {
|
||||
.isTrue();
|
||||
assertThat(TestUtils.getPropertyValue(this.errorChannel, "dispatcher.ignoreFailures", Boolean.class))
|
||||
.isTrue();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<MessageHandler> handlers =
|
||||
TestUtils.getPropertyValue(this.errorChannel, "dispatcher.handlers", Set.class);
|
||||
|
||||
assertThat(handlers).first()
|
||||
.isInstanceOf(LoggingHandler.class)
|
||||
.extracting("order")
|
||||
.isEqualTo(Ordered.LOWEST_PRECEDENCE - 100);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -52,6 +52,8 @@ QueueChannel errorChannel() {
|
||||
====
|
||||
|
||||
NOTE: The default error channel is a `PublishSubscribeChannel`.
|
||||
By default, it has a `LoggingHandler` as a subscriber with an `ERROR` logging level and subscription order as `Ordered.LOWEST_PRECEDENCE - 100`.
|
||||
If you subscribe additional consuming endpoints, that might throw an exception, and you don't want to preempt the logging, ensure that the additional handlers have a higher order.
|
||||
|
||||
The most important thing to understand here is that the messaging-based error handling applies only to exceptions that are thrown by a Spring Integration task that is executing within a `TaskExecutor`.
|
||||
This does not apply to exceptions thrown by a handler that operates within the same thread as the sender (for example, through a `DirectChannel` as described earlier in this section).
|
||||
|
||||
Reference in New Issue
Block a user