dermoritz
dermoritz

Reputation: 13038

Spring integartion LoggingHandler logs all messages to Error

I created a spring boot application that sends Messages through a PublishSubscribeChannel. This Channel is "autowired" as SubscribableChannel interface. I am only subscribing one MessageHandler to this channel, a KafkaProducerMessageHandler.

My problem is that one additional MessageHandler is subscribed and this is an LoggingHandler. It is instantiated with ERROR level. So i see every message logged es error.

I want to know why and where this LoggingHandler is wired (instantiated) and why it is subscribed to the channel - i want to disable it.

( I debugged around a bit but (was not really helpful): The LoggingHandler is instantiated and subscribed after the KafkaHandler. I see this chain EventdrivenConsumer.doStart()<-- ``ConsumerEndpointFactoryBean.initializeEndpoint()<-- ... until reflective calls )

EDIT

As suggested in comments here is some code (i can't share the whole project). My problem is that the code can't explain the behavior. The LoggingHandler is beeing subscribed to my PublishSubscribeChannel for some unknown reason and it is instantiated with error as level for some unknown reason.

The class that subscribes the KafkaHandler:

@Component
public class EventRelay  {

    @Autowired
    private EventRelay( SubscribableChannel eventBus, @Qualifier( KafkaProducerConfig.KAFKA_PRODUCER ) MessageHandler kafka ) {

        eventBus.subscribe( kafka );

    }
}

The class that send events is implementing an proprietary interface with many callback methods:

public class PropEvents implements PropClass.IEvents {

    private SubscribableChannel eventBus;
    private final ObjectMapper om;
    private final String userId;


    public PropEvents( SubscribableChannel eventBus, ObjectMapper om, String userId ) {

        this.eventBus = eventBus;
        this.om = om;
        this.userId = userId;
    }

    @Override
    public void onLogin(  ) {
                 eventBus.send( new OnLoginMessage(... ) ) );
    } 
    //many other onXYZ methods
}

Here is the Factory that produces instances of PropEvents:

@Configuration
public class EventHandlerFactory {

    private final ObjectMapper om;
    private final SubscribableChannel eventBus;

    @Autowired
    public EventHandlerFactory( ObjectMapper om, SubscribableChannel eventBus){
        this.om = checkNotNull( om );
        this.eventBus = checkNotNull( eventBus );
    }

    @Bean
    @Scope( SCOPE_PROTOTYPE)
    public IEvents getEvantHandler(String userId){
        if(Strings.isNullOrEmpty(userId)){
            throw new IllegalArgumentException( "user id must be set." );
        }
        return new PropEvents(eventBus, om, userId);
    }

}

I appreciate any help with debugging or use tooling (e.g. Eclipse Spring tools does not show any hint to a LoggingHandler Bean) to find where and why a LoggingHandler is instantiated and subscribed to my autowired Channel.

My current workaround is to disable logging for LoggingHandler.

My question at a glance Why spring instantiates an LoggingHandler with error level and subscribes it to my SubscribableChannel(provided by PublishSubscribeChannel)? How to disable this?

Upvotes: 0

Views: 907

Answers (1)

Artem Bilan
Artem Bilan

Reputation: 121600

When you @Autowired SubscribableChannel, there should be one in the application context. That might be confusing a bit and mislead, but Spring Integration provides a PublishSubscribeChannel for the global errorChannel: https://docs.spring.io/spring-integration/docs/5.0.2.RELEASE/reference/html/messaging-channels-section.html#channel-special-channels

This one has a LoggingHandler to log error as a default subscriber.

I don't think that it is OK to make your logic based on the errorChannel.

You should consider to declare your own MessageChannel bean and inject it by the particular @Qualifier.

Upvotes: 1

Related Questions