2

I'm building a system using RabbitMQ. One of the things I want to be able to do is direct log messages to different queues based on the severity of the message that's being logged. Errors and exceptions should go to one queue for immediate handling; less-important messages like Trace logs should go somewhere else, so they don't clog up critical logging.

The way I thought to handle this is to set up a Topic exchange and bind two queues to the exchange. Then, my log messages will use their log level in the routing key to get sent to the right queue. However, I have a problem where I don't know the best way to set up the routing keys.

Getting my errors into the right queue is easy - bind two queues to the exchange, one with an Error routing key, and then messages with an Error routing key get sent to it. I want every other kind of message sent to this exchange to go to the other queue. But I don't think you can describe a routing key like !Error or something, or at least it doesn't appear in the RabbitMQ tutorials or the AMQP spec that I can see. If I use a wildcard binding, then my error messages get delivered to both queues.

It looks like I can accomplish this by using an Alternate Exchange (http://www.rabbitmq.com/ae.html) But I would rather stick with straight AMQP if possible, and configuring AEs adds another layer of complexity to my system initialization.

I could also define routing keys for every log level in my system, and explicitly route everything that isn't Error to the low-level queue. But that seems excessively verbose and adds maintenance overhead.

Is there a better way to accomplish my goal than using an AE?

NWard
  • 2,016
  • 2
  • 20
  • 24
  • An AE also fails / is a poor choce because any matchers will prevent the message from going to an AE - the very act of observing the exchange with another binding, etc, will change the expected behavior. – user2864740 Feb 06 '17 at 21:25
  • As of right now, keys *must* for small discriminated sets to be of use and these *must* be explicitly bound: either that or there is no way to 'limit' a binding. This is very unfortunate and I'm surprised this has no proper solution. While one would argue it's not "AMQP 0-9-1", having the ability to form negative sets is very, very handy in real code. Having a more flexible router would be very handy, and I'd gladly trade more ms/message. – user2864740 Feb 06 '17 at 21:27
  • (That is, it is unfortunate there is no 'guard' condition that can be applied to a match: an extension might be able to do this?) – user2864740 Feb 06 '17 at 21:32

1 Answers1

2

Basically the answer is no, is not possibile with the routing key; it's just a "match" thing, not a regex or similar.

What about routing Error on one side, and everything (including error) on the other side? I mean, I suppose you will have less error messages than trace messages (I hope, at least); you will have to "skip" them business side, but I think it will be easier to manage than a RabbitMQ extension.

PS: The nearest thing I can come out with is the Topic Exchange, but it will suffer of the same limitation. Check this for more documentation. PPS: There is also this other SO answer, if you like.

Hope it helps :)

Luca Ghersi
  • 3,261
  • 18
  • 32