How to log Queue name in SimpleMessageListenerCont

2019-07-28 21:29发布

问题:

We're having issues with one of the consumers, and need to debug the code. SimpleRabbitListenerContainerFactory allows to set a ConsumerTagStrategy, which should add tags during logging.

@Bean
public SimpleRabbitListenerContainerFactory analyzeTransactionListenerContainerFactory(ConnectionFactory connectionFactory, AsyncTaskExecutor asyncTaskExecutor) {
    connectionFactory.getVirtualHost());
    SimpleRabbitListenerContainerFactory factory = new  SimpleRabbitListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    factory.setConcurrentConsumers(2);
    factory.setMaxConcurrentConsumers(4);
    factory.setTaskExecutor(asyncTaskExecutor);
    ConsumerTagStrategy consumerTagStrategy = new ConsumerTagStrategy() {
        @Override
        public String createConsumerTag(String queue) {
            return queue;
        }
     };
     factory.setConsumerTagStrategy(consumerTagStrategy);
     return factory;
}

However, the logs still do not have the tag. So there is no way to find what queue/consumer this message is for.

LogLevel=DEBUG; category=org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; msg=Cancelling Consumer: tags=[{}], channel=Cached Rabbit Channel: AMQChannel(amqp://guest@10.17.1.13:5672/,47), acknowledgeMode=AUTO local queue size=0; 

LogLevel=DEBUG; category=org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; msg=Idle consumer terminating: Consumer: tags=[{}], channel=Cached Rabbit Channel: AMQChannel(amqp://guest@10.17.1.13:5672/,47), acknowledgeMode=AUTO local queue size=0; 

How does one add some tags to SimpleMessageListenerContainer logging?

回答1:

Well, looks like you misunderstood the Consumer Key a bit. From the RabbitMQ docs:

consumer-tag consumer-tag

Specifies the identifier for the consumer. The consumer tag is local to a channel, so two clients can use the same consumer tags. If this field is empty the server will generate a unique tag.

The client MUST NOT specify a tag that refers to an existing consumer. Error code: not-allowed

The consumer tag is valid only within the channel from which the consumer was created. I.e. a client MUST NOT create a consumer in one channel and then use it in another. Error code: not-allowed

The SimpleMessageListenerContainer populates its internal map for the consumerTags when it starts to listen to provided queues. If we are listening (consuming) there we can see them from the:

public String toString() {
    return "Consumer: tags=[" + (this.consumerTags.toString()) + "], channel=" + channel
            + ", acknowledgeMode=" + acknowledgeMode + " local queue size=" + queue.size();
}

as you expecting, of course.

But if we don't consumer any more, in case of Channel#basicCancel, for example.

Or... looking to your second log message during idling. When you have an extra Consumer, but there is no message for it.

The code on the matter looks like:

boolean receivedOk = receiveAndExecute(this.consumer); // At least one message received
if (SimpleMessageListenerContainer.this.maxConcurrentConsumers != null) {
    if (receivedOk) {
.....
    }
    else {
        consecutiveMessages = 0;
        if (consecutiveIdles++ > SimpleMessageListenerContainer.this.consecutiveIdleTrigger) {
            considerStoppingAConsumer(this.consumer);
            consecutiveIdles = 0;
        }
   }
}

So, maybe you worry for nothing. And you see the logs only for those extra consumers. For this case you have maxConcurrentConsumers > concurrentConsumers.