[rabbitmq-discuss] Message accounting patch

Eric Windisch eric at grokthis.net
Thu May 14 06:32:34 BST 2009


With the help of Programming Erlang and the gracious folks at Philly  
Lambda, I've completed a patch for message accounting.  Quite simply,  
this patch adds two mnesia tables which count up the messages  
submitted into Rabbit.  One table counts messages per user, and the  
other counts messages per vhost.

To pull data out, you can use the following code:

  Ucount=fun() ->  
mnesia:dirty_read(rabbit_uaudit,mnesia:first(rabbit_uaudit)) end.
  mnesia:transaction(Ucount).
  Vcount=fun() ->  
mnesia:dirty_read(rabbit_vaudit,mnesia:first(rabbit_vaudit)) end.
  mnesia:transaction(Vcount).

This example will grab the data from the first entry from each table.   
You can clearly substitute the Key argument with a string, or write a  
more complicated expression as you might desire.

Regards,
Eric Windisch



diff -r 2ce3d18b4383 include/rabbit.hrl
--- a/include/rabbit.hrl	Fri Apr 24 17:08:19 2009 +0100
+++ b/include/rabbit.hrl	Thu May 14 05:17:18 2009 +0000
@@ -52,6 +52,8 @@
  -record(exchange, {name, type, durable, auto_delete, arguments}).

  -record(amqqueue, {name, durable, auto_delete, arguments, pid}).
+
+-record(counter, {name, count}).

  %% mnesia doesn't like unary records, so we add a dummy 'value' field
  -record(route, {binding, value = const}).
@@ -111,6 +113,10 @@
        #binding{exchange_name    :: exchange_name(),
                 queue_name       :: queue_name(),
                 key              :: binding_key()}).
+-type(counter() ::
+      #counter{name          :: string(),
+               count         :: non_neg_integer()}).
+
  %% TODO: make this more precise by tying specific class_ids to
  %% specific properties
  -type(undecoded_content() ::
diff -r 2ce3d18b4383 src/rabbit_mnesia.erl
--- a/src/rabbit_mnesia.erl	Fri Apr 24 17:08:19 2009 +0100
+++ b/src/rabbit_mnesia.erl	Thu May 14 05:17:18 2009 +0000
@@ -143,7 +143,16 @@
         {disc_copies, [node()]}]},
       {rabbit_queue,
        [{record_name, amqqueue},
-       {attributes, record_info(fields, amqqueue)}]}].
+       {attributes, record_info(fields, amqqueue)}]},
+     {rabbit_vaudit,
+      [{record_name, counter},
+       {attributes, record_info(fields, counter)},
+       {disc_copies, [node()]}]},
+     {rabbit_uaudit,
+      [{record_name, counter},
+       {attributes, record_info(fields, counter)},
+       {disc_copies, [node()]}]}
+	].

  table_names() ->
      [Tab || {Tab, _} <- table_definitions()].
diff -r 2ce3d18b4383 src/rabbit_reader.erl
--- a/src/rabbit_reader.erl	Fri Apr 24 17:08:19 2009 +0100
+++ b/src/rabbit_reader.erl	Thu May 14 05:17:18 2009 +0000
@@ -613,6 +613,13 @@
                                            user = User},
                             sock = Sock}) ->
      ok = rabbit_access_control:check_vhost_access(User, VHostPath),
+
+ 	%% EricW: I'm assuming that this is a decent place to
+ 	%% do message accounting. We can get the VHost and User
+ 	%% at any rate...
+ 	mnesia:dirty_update_counter(rabbit_vaudit,VHostPath,1),
+ 	mnesia:dirty_update_counter(rabbit_uaudit,User,1),
+
      NewConnection = Connection#connection{vhost = VHostPath},
      KnownHosts =  
format_listeners(rabbit_networking:active_listeners()),
      Redirects = compute_redirects(Insist),






More information about the rabbitmq-discuss mailing list