Recently I stumbled into a problem where I wanted to access, and Read messages from the Dead Letter Queue. Because Azure has changed so much over time, there’s now a massive amount of misinformation on the best way to read messages from the dead letter queue.
In this post, I wanted to show the way I accessed these messages from a C# console application in 2020. The approach to this can be a little bit convoluted, hopefully, Microsoft makes this process more streamlined in the future.
Accessing the Dead Letter Queue (DLQ)
Initially, you’ll want to connect to the Azure Service Bus. The Microsoft.Azure.ServiceBus nuget package can be found here. Be careful not to get the wrong package, the Microsoft.ServiceBus package doesn’t work in the same way! Once we have the package installed, you need the following details to hand:
- The Connection string. Typically this looks like: “Endpoint=sb://theurloftheconnection;SharedAccessKeyName=aKeyName;SharedAccessKey=fdgsdfgsdfgsdfgsd=”
- The topic you’re looking to download DLQ messages from.
- The subscription you’re looking to download DLQ messages from.
All of these variables will be essential to helping you access the Dead Letter Queue data, but once you have the above variables, you’re good to start!
Creating a message reader
Using the variables above, we can make a quick method that will access a message from the DLQ. This is the fundamental mechanism for accessing and reading data from the DLQ.
private static async Task GetMessage() { string connection = "Endpoint=sb://theurloftheconnection;SharedAccessKeyName=aKeyName;SharedAccessKey=fdgsdfg="; string topic = "DavesChat"; string subscription = "TestQueue"; var subPath = EntityNameHelper.FormatSubscriptionPath(topic, subscription); var deadLetterPath = EntityNameHelper.FormatDeadLetterPath(subPath); var receiver = new MessageReceiver(connection, deadLetterPath, ReceiveMode.PeekLock); var message = await receiver.PeekAsync(); }
In the above C# code, you can see that we’ve set all of our variables (with fake data of course) and started to use the Azure tools to properly access the data. Then we can build an entity path using the helpful EntityNameHelper class. Once the entity path is created, we can generate a dead letter path using the same helper class. This leads to us creating an azure message receiver that uses the connection string, with the dead letter path string. Additionally, you’ll notice that there’s a PeekLock receive mode variable set. Using this variable ensures that the messages accessed are peeked and not deleted from the queue. Alternatively, you could use “RecieveAndDelete” which would… unsurprisingly receive the message and delete it from the queue. Obviously, I’d recommend testing out how these variables work in a test environment, once DLQ messages are removed they aren’t possible to recover.
Read messages from the Dead Letter Queue for multiple messages
Now we can download a message, but how do we download multiple? There’s an integer argument that can be passed into PeekAsync, but it gets you up to that number of messages… e.g. if you passed in the number 10 it’d download up to 10 messages. If you have any idea why they’ve done it this way, please comment below!
Alternatively, we can loop over the receiving code to pull down as many messages as we want.
private static async Task<IEnumerable<Message>> GetMessage(int messageCount) { string connection = "Endpoint=sb://theurlofthnection;SharedAccessKeyName=aKeyName;SharedAccessKey=fdgsdfg="; string topic = "DavesChat"; string subscription = "TestQueue"; var subPath = EntityNameHelper.FormatSubscriptionPath(topic, subscription); var deadLetterPath = EntityNameHelper.FormatDeadLetterPath(subPath); var receiver = new MessageReceiver(connection, deadLetterPath, ReceiveMode.ReceiveAndDelete); List<Message> messageList = new List<Message>(); while(messageCount-- > 0) { messageList.Add( await receiver.PeekAsync()); } return messageList; }
Because this code peeks at each of the messages on the DLQ , it will return the number of messages you ask for from the DLQ.
And that is how you how to read messages from dead-letter queue azure c#.
Hopefully, that’s useful in enabling you to get ahold of your DLQ messages. If you’re reading this, I’d love to know what you’re using the Azure Service Bus for and how you’re experiencing it. Please comment below!
For more detail on the await and async methods used above you can read my The Amazing Await and Async in C# 2021 post.
I’d love to know what you’re using the Azure Service Bus for and how you’re experiencing it.
IMO, it depends on your message guarantee granularity and the efficiency of retrieving messages from the queue. If a message is small, retrieving them one at a time is cost-heavy but gives you isolation. In the balance, you might want to grab 10, do your processing before going for more messages… all depends on how many and where you want to spend resources.
HTH
Absolutely Richard, great points. The first time I used this code was actually in relation to software for a distribution company that required permission to be given for each batch of goods that was sent out. Anything hitting the dead letter queue was often a sign that there had been a wider system failure somewhere along the chain, so every time there was an issue….. there would be thousands of messages.
Obviously if better constrained, you’d hope there’d be isolated messages on the DLQ which would inevitably be better dealt with individually as you mentioned.
Thanks for your input!
very interesting points you have noted , thankyou for posting .
Thank you, appreciate the feedback!