61

Does anyone know if there's a way to check the number of messages in a RabbitMQ queue from a client application?

I'm using the .NET client library.

Prof. Falken
  • 24,226
  • 19
  • 100
  • 173
Pablote
  • 4,745
  • 9
  • 39
  • 46

9 Answers9

76

You can actually retrieve this via the client.

When you perform a queue_declare operation, RabbitMQ returns a tuple with three values: (<queue name>, <message count>, <consumer count>). The passive argument to queue_declare allows you to check whether a queue exists without modifying the server state, so you can use queue_declare with the passive option to check the queue length.

Not sure about .NET, but in Python, it looks something like this:

name, jobs, consumers = chan.queue_declare(queue=queuename, passive=True)
Pang
  • 9,564
  • 146
  • 81
  • 122
mmalone
  • 1,816
  • 16
  • 10
  • This should be the accepted answer, even if he did miss Basic.Get as the 2nd source of this info. – Michael Dillon Jan 17 '12 at 07:49
  • 1
    What is chan here and how to import it ? – Kishan Mehta Apr 21 '17 at 04:03
  • This is no longer the best way to do it. – BillHaggerty Aug 09 '17 at 19:01
  • 25
    @Theyouthis It's very frustrating to find comments like "This is no longer the best way to do it" without any sort of reference to the improved way that you are referring to. Why not share your findings? – spender Jan 18 '18 at 14:43
  • 1
    Use the MessageCount() function on your IModel. If you scroll down you will see two answers mention the function on this very question. – BillHaggerty Jan 18 '18 at 18:46
  • This is done differently nowadays: `result = channel.queue_declare(queue=queuename, passive=True).method`. And then you would just access `result.message_count` because the result is not unpackable. `` – Ionut-Alexandru Baltariu Jun 06 '22 at 12:54
  • Used this passive declaration in java for some time, but seems that lately it is so slow to update. I switched to http client requesting rabbit api, since it was not updating as it should (almost always it showed to have 0 total messages). – Bojan Vukasovic Aug 30 '22 at 16:13
18

I am 2 years too late but I was searching for it myself and found that rabbitmq gives u simple script to communicate to erlang nodes..its in sbin folder where the starting script for RabbitMQ is located..so you can basically say

./rabbitmqctl list_queues

this will display the queues along with the count of messages pending to those queues similarly you can also say

./rabbitmqctl list_channels
./rabbitmqctl list_connections

etc. For more info you can visit here

Rafi
  • 805
  • 6
  • 12
16

If you want to do this in .NET, check which version of the client library you are using.

I'm using the 2.2.0 version and I had to use BasicGet(queue, noAck).
In this version of the library, QueueDeclare() only returns a string containing the queue name.

BasicGetResult result = channel.BasicGet("QueueName", false);
uint count = result != null ? result.MessageCount : 0;

I know from the 2.6.1 version, QueueDeclare() returns an object of type QueueDeclareOk.

QueueDeclareOk result = channel.QueueDeclare();
uint count = result.MessageCount;

Alternatively, you can call from the command line:

<InstallPathToRabbitMq>\sbin\rabbitmqctl.bat list_queues

And you see the following output:

Listing queues...
QueueName 1
...done.

Pang
  • 9,564
  • 146
  • 81
  • 122
Ralph Willgoss
  • 11,750
  • 4
  • 64
  • 67
9

I'm using version 3.3.1 of the .NET client library.

I use the following, which is very similar to Ralph Willgoss's second suggestion, but you can supply the queue name as an argument.

QueueDeclareOk result = channel.QueueDeclarePassive(queueName);
uint count = result != null ? result.MessageCount : 0;
Pang
  • 9,564
  • 146
  • 81
  • 122
Mike
  • 827
  • 11
  • 27
7

my little snippet based on Myydrralls' answer. I think if he had code in his answer I might have noticed it much quicker.

public uint GetMessageCount(string queueName)
{
    using (IConnection connection = factory.CreateConnection())
    using (IModel channel = connection.CreateModel())
    {
        return channel.MessageCount(queueName);
    }
}
always-a-learner
  • 3,671
  • 10
  • 41
  • 81
6

You can use the IModel's MessageCount method, documented here

http://www.rabbitmq.com/releases/rabbitmq-dotnet-client/v3.6.4/rabbitmq-dotnet-client-3.6.4-client-htmldoc/html/type-RabbitMQ.Client.IModel.html#method-M:RabbitMQ.Client.IModel.MessageCount(System.String)

edit: I know this is a very old post, but it is the first google response, and I hope it will help people looking for this answer in the future.

Myddraall
  • 103
  • 1
  • 9
5

Update: it appears that the pika implementation of queue_declare(..) has changed since mmalone's very helpful post.

In python/pika (v0.9.5) it's still possible to check the queue depth via pika, but it requires a slightly more indirect approach.

queue_declare(...) passes a method object into its callback function, which you can then inspect. For example, to check the number of messages and consumers in the queue named 'myQueue':

def cbInspect(qb):
    messagesInQueue = qb.method.message_count
    print "There are %d messages in myQueue" % messagesInQueue

    consumersInQueue = qb.method.consumer_count
    print "There are %d consumers in myQueue" % consumersInQueue

    return

myChannel = channel.queue_declare(callback=cbInspect, queue='myQueue', passive=True)

Hope this helps, and please go easy on me, I'm new around here :-)

tohster
  • 6,973
  • 5
  • 38
  • 55
  • channel.queue_declare returns an object that contains the current message count so if you want to avoid a callback, you can also access the message count like this: myChannel.method.message_count – corford Mar 11 '14 at 17:46
5

I was able to get the size/depth of queue from python program.

  1. using py_rabbit
    from pyrabbit.api import Client
    cl = Client('10.111.123.54:15672', 'userid', 'password',5)
    depth = cl.get_queue_depth('vhost', 'queue_name')
  1. kombu [a python package usually comes with celery installation]
conn = kombu.Connection('amqp://userid:password@10.111.123.54:5672/vhost')
conn.connect()
client = conn.get_manager()
queues = client.get_queues('vhost')
for queue in queues:
    if queue == queue_name:
    print("tasks waiting in queue:"+str(queue.get("messages_ready")))
    print("tasks currently running:"+str(queue.get("messages_unacknowledged")))

the ip address is just an example.

Edit:

3

I have found a better way to do this . curl appears to be more convenient and faster way to do it


curl -s -i -u $user:$password http://$host_ip_address:15672/api/queues/$vhost_name/$queue_name | sed 's/,/\n/g' | grep '"messages"' | sed 's/"messages"://g'
Mir Al-Masud
  • 51
  • 1
  • 5
3

At least as of RabbitMQ 3.3.5, you can do this in a C# program without any RabbitMQ client library by calling the RabbitMQ Management HTTP API:

// The last segment of the URL is the RabbitMQ "virtual host name". 
// The default virtual host name is "/", represented urlEncoded by "%2F".
string queuesUrl = "http://MY_RABBITMQ_SERVER:15672/api/queues/%2F";

WebClient webClient = new WebClient { Credentials = new NetworkCredential("MY_RABBITMQ_USERNAME", "MY_RABBITMQ_PASSWORD") };
string response = webClient.DownloadString(queuesUrl);

The username and password are the same as those you use to log into the RabbitMQ management console UI.

Response will be a JSON string with the list of queues, including their message counts, among other properties. (If you like, you can deserialize that JSON into a C# object using a library like Json.NET.)

The API documentation is installed along with the RabbitMQ management console and should be available on that server at http://MY_RABBITMQ_SERVER:15672/api .

Jon Schneider
  • 25,758
  • 23
  • 142
  • 170